0

I'm using Boost for a multi-producer, single-consumer queue, and want the consumer to quit when queue.empty() && [no more producers]. However, determining when there are no more producers is non-trivial. In particular, I want to avoid any race conditions where the consumer might think there are no more producers but there really are.

Ideas:

  1. Reference count: Each producer increments a ref count as its first action and decrements it as it exits

  2. Check if each thread is running, using joinable()

Neither idea is good.

#1 suffers from these problems:

  • Ref count must be atomic (solved using Boost.Atomic)
  • What happens if consumer checks in between creation of thread and incrementing reference count
  • Paranoia: what if thread terminates unexecpetedly and can't decr its ref count?

#2 suffers from these problems:

  • joinable doesn't mean not terminated (it can have completed itself but still be a joinable boost::thread)
  • How does consumer know what all the producer threads are? Even if a thread_group is used to hold them, there is no way to enumerate the thread group, or to ask "is any joinable?"

I think the problem could be solved using monitors, but I'm not sure how to do that.

What is the standard way to detect when there are no more producers, and how is this done using Boost?

SRobertJames
  • 8,210
  • 14
  • 60
  • 107

1 Answers1

0

IMHO, the 1st idea is good and the problems are artifical.

As already written the std::atomic or boost::atomic solves the 1st problem.

The 2nd problem is solved by incrementing the reference count before the thread constructor call and proper exception and error handling in between these two lines (i.e. producer_count++ and c'tor call).

The 3rd problem. It is not clear how a thread can be terminated unexpectedly. I can imagine only a not handled exceptions/signals. In case of not handled exceptions, the std::terminate function (std::thread help, boost::thread help) is called and does not matter either the reference counter is decremented or not. I think the situation with not handled the Linux signals or the Windows Structured Exceptions is similar.

megabyte1024
  • 8,482
  • 4
  • 30
  • 44