There are a couple of logic flaws in your job pool example which are causing 
your issues. Nothing particularly Nim specific, but here's a breakdown.
    
    
    while workID < NSUBMISSIONS: # This will run ceil(NSUBMISSIONS / NTHREADS) 
* NTHREADS items
        for thread in pool.mitems:
          let channel = thread.output.tryRecv() # Need to retry this until done 
for each loop or block
          if channel.dataAvailable: # assume state == ThreadComm.Ready if 
anything received
            inc workID
            thread.input.send(ThreadComm.Begin)
      echo "workId: ", workId # added this to print actual number of jobs run
    
    
    Run

The first is how you're divvying up the number of jobs. You have a thread pool 
size of 8, which doesn't fit evenly into your number of submissions of 100. The 
logic in your loop will try and submit `ceil(100 / 8).int * 8 ≈ 104` jobs.

The second logic error introduces the stochastic failure. The 
`thread.output.tryRecv()` can run _before_ individual threads are finished. You 
would need to keep track of the finished threads, and keep retrying the 
unfinished threads. Alternatively you can use `thread.output.recv()` instead 
which will block until each thread is done per cycle. Modifying your code to 
use `recv` it then outputs 1040 every time with 104 work units done.

In other words, thread pools are tricky and you'd need to rethink your logic 
for how you submit work to threads and wait for them for finish. Usually you'll 
have one channel (queue) shared between multiple workers which will use system 
primitives or other methods to let only one thread grab a work chunk at a time. 

Reply via email to