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.