1

In this blog post (2010), someone is trying to solve the producer/consumer problem using Boost::strand facility. I have the feeling that he missed the point and that his program never runs simultaneously some producer and some consumer, but I'm not that expert of boost library to get confident about it.

  • He's got only one strand, on which both producer() and consumer() calls are dispatched by some timers;
  • He's got two thread, both invoking io_service::run()

Yet, one strand only with the guarantee that "none of those handlers will execute concurrently" also means that we'll be either producing or at a time, while I'd say nothing should prevent a producer from producing unit U+t while consumer uses unit U, right ?

   void producer_consumer::producer() {
     if ( count_ < num)   {
       ++count_;
       intvec_.push_back(count_);
       std::cout << count_ < " pushed back into integer vector." << std::endl;
       timer1_.async_wait(strand_.wrap(
           boost::bind(&producer_consumer::producer, this))); // loops back
       timer2_.async_wait(strand_.wrap(
           boost::bind(&producer_consumer::consumer, this))); // start consumer
     }
   }

Or am I missing the fact that there would be some File::async_read() accepting a strand-wrapped-"produce" function as completion callback and a similar Socket::ready-to-write-again that would explain that his proposal make sense as long as "producer()" and "consumer()" are actually the monitor-protected parts that interface with the shared buffer ?

PypeBros
  • 2,607
  • 24
  • 37
  • 1
    The impression I got from the blog that the author suggests using Boost.Asio's `strand` for synchronization in preference to other synchronization constructs whenever possible, and provided a simplified example to demonstrate using `strand`. Personally, I disagree with the thesis, as I prefer using `strand` _when_ it makes sense, not "_whenever possible_", and found the supporting evidence lacking, as the consequences are the result of multithreading, and not the synchronization mechanism. – Tanner Sansbury Sep 30 '13 at 17:28

1 Answers1

2

The example code tends to focus much more on demonstrating strand as a synchronization mechanism, rather than providing a solution for the producer-consumer problem.

For a motivational case of using strand to solve a producer-consumer problem, consider a GUI based chat client using TCP. The GUI can produce multiple messages, trying to send a message before the previous message has been written to the connection. Meanwhile, the application needs to consume and write each message to the TCP connection while preserving the messages, resulting in no interleaving data. Composed operations, such as async_write, requires that the stream perform no other write operations until the composed operation completes. To account for these behaviors:

  • A queue can buffer chat messages.
  • The GUI can post an operation into strand that will:
    • Add the chat message to the queue.
    • Conditionally start the consumer.
  • The consumer is an asynchronous call-chain that reads from the queue and writes to the socket within the strand.

See this answer for an implementation.

Community
  • 1
  • 1
Tanner Sansbury
  • 51,153
  • 9
  • 112
  • 169
  • By "conditionally start the consumer", I guess you imply the existence of some wake_thread_now() call that wouldn't prevent the thread to go to sleep later if awake right now. – PypeBros Oct 02 '13 at 08:58
  • meanwhile, it seems to me that if we have the queue, it solves the prod/cons problem you presented by its mere presence (unless pushing to the queue might block the GUI thread). – PypeBros Oct 02 '13 at 09:09
  • @sylvainulg: Conditionally starting is intentionally vague. It could be some `wake_thread_now()`, but it could also be starting an asynchronous chain, as shown in the linked answer (`write()` -> `writeHandler()` chain). With how `strand` works, it is more likely that the GUI creates an operation to push into the queue and immediately returns, rather than directly push into the queue where it may block. – Tanner Sansbury Oct 02 '13 at 14:11