Pergunta

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 ?

Foi útil?

Solução

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top