Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 多线程访问队列的推荐模式…工作线程应该做什么?_C++_Multithreading_Queue - Fatal编程技术网

C++ 多线程访问队列的推荐模式…工作线程应该做什么?

C++ 多线程访问队列的推荐模式…工作线程应该做什么?,c++,multithreading,queue,C++,Multithreading,Queue,我有一个由线程a添加到的对象队列。线程B正在从队列中删除对象并对其进行处理。可能有多个线程A和多个线程B 当队列被“推”到时,以及当“前端”被“推”到并从中“弹出”时,我使用互斥锁,如下面的伪代码所示: 线程A调用此项以添加到队列: void Add(object) { mutex->lock(); queue.push(object); mutex->unlock(); } 线程B按如下方式处理队列: object GetNextTargetToWorkO

我有一个由线程a添加到的对象队列。线程B正在从队列中删除对象并对其进行处理。可能有多个线程A和多个线程B

当队列被“推”到时,以及当“前端”被“推”到并从中“弹出”时,我使用互斥锁,如下面的伪代码所示:

线程A调用此项以添加到队列:

void Add(object)
{
    mutex->lock();
    queue.push(object);
    mutex->unlock();
}
线程B按如下方式处理队列:

object GetNextTargetToWorkOn()
{
    object = NULL;

    mutex->lock();
    if (! queue.empty())
    {
        object = queue.front();
        queue.pop();
    }
    mutex->unlock();

    return(object);
}

void DoTheWork(int param)
{
    while(true)
    {
        object structure;

        while( (object = GetNextTargetToWorkOn()) == NULL)
            boost::thread::sleep(100ms); // sleep a very short time

        // do something with the object
    }    
}
让我烦恼的是,如果没有对象,就去睡觉。虽然存在要处理的对象,但这很好。但是当线程正在等待工作时,有两个问题

a) while循环正在消耗资源
b) 睡眠意味着浪费的时间是一个新的对象进入处理


有更好的模式来实现同样的功能吗?

如果使用旋转等待,更好的设计是使用监视器。请阅读有关的详细信息。 可以找到一个使用std::condition_变量的跨平台解决方案,并提供了一个很好的示例

a) while循环正在消耗资源 b) 睡眠意味着浪费的时间是一个新的对象进入处理

根据我的经验,您使用的睡眠实际上“修复”了这两个问题

a) 资源消耗量很小,占用的可用cpu周期非常少

b) 睡眠是而不是在我开发的操作系统上浪费的时间

c) 睡眠可以影响“反应时间”(又称延迟),但很少成为问题(除了中断)

睡眠时间可能比在这个简单循环中花费的时间长几个数量级。i、 e.这并不重要


IMHO-这是“好邻居”策略的一个正常实现,即尽快放弃处理器


在我的桌面AMD64双核Ubuntu15.04上,一个信号量强制的上下文切换大约需要13分钟

100毫秒==>100000美元。。这是4个数量级的差异,即非常小

在我使用过的5个操作系统(Linux、vxWorks、OSE和其他几个嵌入式系统操作系统)中,睡眠(或其等效物)是放弃处理器的正确方式,这样当一个线程处于睡眠状态时,它就不会被阻止运行另一个线程



注意:某些操作系统的睡眠可能不会放弃处理器。所以,你应该始终确认。我没找到。哦,但我承认我没有在Windows上做过很多工作。

要使用的“模式”是一个条件变量。。。或信号量……旁注:不要显式调用
lock
unlock
。C++11为您提供了异常/程序员安全的RAII管理
互斥锁
请使用它。在Windows上,(在我的i7上)通过将一个单元发送到线程正在等待的信号量(假设有一个内核可用),使线程运行需要5-8个U。Windows Sleep()API执行您预期的操作—从调用线程中删除执行,直到睡眠间隔结束,此时线程再次准备就绪(然后在内核可用时运行)。IIRC虽然如此,发送到等待线程的信号量为等待线程提供了临时优先级提升,但Sleep()expiry没有。是的,监视器模式对我来说非常有效-谢谢