【问题标题】:C++11 - Thread that can wait on several different events? [closed]C ++ 11 - 可以等待几个不同事件的线程? [关闭]
【发布时间】:2020-03-04 15:28:15
【问题描述】:

我正在用 C++ 编写一个餐厅模拟程序,以练习该语言,尤其是 C++11 线程。

我打算使用可以执行以下操作的线程服务器类(即服务员):

  • 收到新工作发布到全局餐桌的通知并接受工作(即安排刚进入餐厅的派对)

  • 收到准备下订单并开始工作的一方的通知(即访问该方的餐桌,接受他们的订单并将其提交到酒吧或厨房的工作队列)

  • 在订单完成时收到通知,从厨房或酒吧获取订单并将其送到正确的餐桌

这里最大的问题是我想要的行为类似于同时等待几个条件变量,我从this post 读到这是不可能的。

我宁愿不使用忙等待,因为这些任务可能需要几分钟或更长时间,这会消耗大量不必要的 CPU。

很可能,我想使用条件变量和增强信号的某种组合,但我不确定如何将其设计为最有效和简洁。

非常感谢任何有关设计或阅读的建议。

提前致谢!

【问题讨论】:

  • 太宽泛/主要是意见,有很多可能的方法。抱歉,这种问题不适合 stackoverflow。
  • 既然你提到了队列,生产者/消费者队列是一种完全可等待的线程间通信形式:github.com/cameron314/readerwriterqueue
  • @SamVarshavchik 对不起,我的帖子是基于什么观点的呢?我正在尽我最大的努力不要变得粗鲁,但我发现你的评论是不知情和不满的。我真的只是在寻找潜在的设计建议来解决我的用例。 Stack Overflow 是否禁止设计问题?请赐教。我是社区的新手。
  • @parktomatomi 我很欣赏这个建议。不幸的是,生产者/消费者只能承担服务员 1/3 的责任。
  • 是的,对于 stackoverflow,设计问题通常过于宽泛/自以为是/离题。这是因为如果你问两个 C++ 开发人员设计 X 的最佳方式是什么,你会得到三个不同的答案。

标签: c++ multithreading c++11 asynchronous


【解决方案1】:

当我需要一个线程同时等待多个事物时,我发现select() 可以很好地作为实现该行为的基础。特别是,您可以将select() 设置为阻塞,直到指定的一组套接字中的至少一个已准备好在其传入数据缓冲区中读取数据。

那么,当您的程序与网络无关时,这有什么用处呢?因为您可以在生成线程之前调用pipe()socketpair(),并将管道的接收端(或套接字对的任一端)传递给线程,以便将其传递给select()。然后当另一个线程希望该线程唤醒并做某事时,它可以write() 一个虚拟字节到管道/套接字对的另一端,这将导致select()-ing 线程从select() 返回,因此FD_ISSET() 将指示接收套接字已准备好读取。基于此,线程可以read() 在其文件描述符上接收到的虚拟字节(并丢弃它们),然后执行任何适当的操作。之后,它可以再次调用select() 重新进入休眠状态,直到收到下一个传入的“触发字节”。

以上对于简单的“嘿,现在做点什么”式的通信就足够了,如果线程之间必须传递很少或没有数据;对于更精细的数据传递,我通常将上述触发机制与某种受 Mutex 保护的命令/消息对象 FIFO 队列相结合,这样“触发”线程将一个或多个消息对象添加到 FIFO 队列中,然后发送dummy-byte,而“接收”线程在从select() 唤醒后,将从其 FIFO 队列中抓取所有消息对象,然后依次处理每个对象。

【讨论】:

  • 我真的很喜欢这种方法,甚至不知道select() 的存在,因此我在 C++ 中做这个项目(因为我不太了解这种语言)。 感谢您,您不只是回避我的问题。我真的很感激它
猜你喜欢
  • 1970-01-01
  • 2015-04-24
  • 1970-01-01
  • 2020-10-04
  • 2011-07-21
  • 1970-01-01
  • 1970-01-01
  • 2019-02-11
相关资源
最近更新 更多