使用spsc_queue来避免单生产者单消费者程序中的繁忙等待
Avoiding busy waiting in a Single Producer Single Consumer Program viz using spsc_queue
我试图实现单个生产者(主线程)和单个消费者(从主线程派生的子线程)问题,因此根据我的搜索,我得到了spsc_queue
作为boost库提供的最佳无锁数据结构。现在从他们的示例代码中,消费者函数看起来像这样:
void consumer(void)
{
int value;
while (!done) {
while (queue.pop(value))
++consumer_count;
}
while (queue.pop(value))
++consumer_count;
}
现在,可能会发生spsc_queue may remain empty for sometime
,所以为了避免繁忙的等待,我在代码中引入了睡眠:
void consumer(void)
{
int value;
while (!done) {
if (spsc_queue.empty())
{
cout << "Waiting for data....n";
this_thread::sleep_for (chrono::milliseconds(100));
}
else
{
while (spsc_queue.pop(value))
{
++consumer_count;
}
}
}
while (spsc_queue.pop(value))
++consumer_count;
}
这样做是正确的吗?或者,有没有更好的方法?我遇到了一些图书馆,如libevent
或libev
或boost::asio::io_service
-有人能帮我找出最好的方法来避免忙碌的等待吗?
我关心的是性能和代码必须是无锁和无等待(如果可能的话)。
你的目标和你的需求不一致。
wait-free:等待直到一个元素已经可用,将排除此属性。
lock-free:你的目标是在元素可用之前不做任何工作,即你想要阻塞。这再次与无等待和无锁相矛盾。
你真正想要的是像
这样的东西if (spsc_queue.empty()) {
doSomethingElse();
}
或者简单地继续忙循环。
也许最接近你想要的是:
if (spsc_queue.empty()) {
std::this_thread::yield();
}
重新调度线程,让其他线程完成它们的工作。但是,您将放弃您的时间片,并且可能无法在25-100ms之前重新安排。
为什么代码必须是无锁的?既然队列为空的概率似乎相当高,为什么需要无锁代码呢?如果那样的话,你没有什么好处。
另一方面,如果空队列的概率很低,那么繁忙循环会随着时间的推移而摊销。无论如何,您不会在繁忙循环中花费太多时间,但要尽可能快地取出元素(以偶尔的繁忙等待为代价)。
相关文章:
- Mongodb c++驱动程序:如何查询元素的数组
- C++,系统无法执行指定的程序
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- C++ Windows 驱动程序MSB3030无法复制该文件,因为它找不到
- 重载操作程序时出错>>用于类中的字符串 memebr
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 试图在visual studio上用C++创建一个桌面应用程序
- 模板元程序查找相似的连续类型名称
- FFmpeg:制作一个应用程序比直接使用ffmepg更好吗
- 如何通过cpp程序运行shell脚本
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- IPC使用多个管道和分支进程来运行Python程序
- 如何将c++程序的一些输出传递给shell,以便在shell中使用
- 使用C++程序合并排序没有得到正确的输出
- 多线程程序生产者/消费者[BOOST]
- 我定义的Mutex类中的逻辑错误,以及我在生产者-消费者程序pthreads中使用它的方式
- 生产者和消费者无限期地等待应用程序何时退出
- 使用spsc_queue来避免单生产者单消费者程序中的繁忙等待
- 在一个简单的c++ 11四线程程序中,如果我注释标准输出打印行,我的两个消费者线程就不会返回