boost::strand 生产者/消费者有意义吗?
Posted
技术标签:
【中文标题】boost::strand 生产者/消费者有意义吗?【英文标题】:does boost::strand producer/consumer make sense? 【发布时间】:2013-09-30 13:00:04 【问题描述】:在this blog post (2010) 中,有人试图使用 Boost::strand 工具来解决生产者/消费者问题。我觉得他没有抓住重点,他的程序从来没有同时运行一些生产者和一些消费者,但我不是那种对 boost 库有信心的专家。
他只有一条链,其中producer()
和consumer()
调用都由一些计时器调度;
他有两个线程,都调用io_service::run()
然而,只有保证“这些处理程序都不会同时执行”的一条链也意味着我们将要么一次生成或,而我想说什么都不应该阻止生产者生产单位 U+t 而消费者使用单位 U,对吧?
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
或者我是否错过了这样一个事实,即有一些 File::async_read()
接受一个 strand-wrapped-"produce" 函数作为完成回调和一个类似的 Socket::ready-to-write-again 来解释他的提议使只要“producer()”和“consumer()”实际上是与共享缓冲区接口的受监视器保护的部分,是否有意义?
【问题讨论】:
我从博客中得到的印象是,作者建议尽可能使用 Boost.Asio 的strand
进行同步,而不是其他同步结构,并提供了一个简化的示例来演示如何使用 strand
。就我个人而言,我不同意这个论点,因为我更喜欢使用strand
when 它是有意义的,而不是“只要有可能”,并且发现缺乏支持证据,作为后果是多线程的结果,而不是同步机制。
【参考方案1】:
示例代码更侧重于将strand
演示为一种同步机制,而不是为producer-consumer problem 提供解决方案。
对于使用strand
解决生产者-消费者问题的励志案例,请考虑使用 TCP 的基于 GUI 的聊天客户端。 GUI 可以产生多条消息,尝试在前一条消息写入连接之前发送一条消息。同时,应用程序需要在保存消息的同时消费并写入每条消息到 TCP 连接,从而不会产生交错数据。组合操作(例如async_write
)要求流在组合操作完成之前不执行其他写入操作。要考虑这些行为:
strand
,这将:
将聊天消息添加到队列中。
有条件地启动消费者。
消费者是一个异步调用链,它从队列中读取并写入strand
中的套接字。
请参阅this 答案以获取实现。
【讨论】:
通过“有条件地启动消费者”,我猜你暗示了一些 wake_thread_now() 调用的存在,如果现在醒着,它不会阻止线程稍后进入睡眠状态。 同时,在我看来,如果我们有队列,它就可以解决您仅通过它的存在而提出的 prod/cons 问题(除非推送到队列可能会阻塞 GUI 线程)。 @sylvainulg:有条件的开始是故意模糊的。它可能是一些wake_thread_now()
,但它也可能正在启动一个异步链,如链接答案(write()
-> writeHandler()
链)所示。以strand
的工作方式,GUI 更有可能创建一个操作以推入队列并立即返回,而不是直接推入可能阻塞的队列。以上是关于boost::strand 生产者/消费者有意义吗?的主要内容,如果未能解决你的问题,请参考以下文章
我需要在这个服务器模型中使用 boost::strand 吗?