Rust simple job queue

No. The child threads block on the iterator when it's empty but still connected. The channel (queue) can drain and refill as many times as it likes.

A channel becomes disconnected when (all clones of) either the tx or rx handles are dropped; in other words:

  • if the tx was dropped, no new items can be added. In this case, the rx will still produce items until the channel is also empty, and then return None. This lets the queue drain and then the threads exit gracefully.
  • if the rx was dropped, no items added can ever be removed. In this case, the tx.send() will error.

If you did reorder them, and used a bounded channel, your main thread would probably block in s.send() on a full channel before even starting the workers. You could, of course, start the sender in a thread as well, then it doesn't matter which order you put them.

The race condition we do have to take care of, though, is the program main thread exiting before all the work is done. As I alluded to, in the example above, after loading all the input lines into the channel, you will need to know how to wait for the work to be done. That means either blocking the main thread on join() of each of the workers, or having some other way. In my case, there are more threads than shown here, and I can join on just one of them.

Edit footnote: I was sure I'd written about this recently too: Test for when crossbeam_channel is "disconnected"?

1 Like