c++ - 在不使用自旋锁的情况下在空队列上暂停线程

标签 c++ multithreading performance spinlock

我有一些代码是这样工作的:

std::queue<int> a_queue;
bool exit = false;

void MainThreadFunc(int somedata)
{
    a_queue.push(somedata);
}

void WorkerThreadFunc()
{
    while (true)
    {
        if (exit)
            return;

        while (a_queue.empty());

        DoSomethingWithData(a_queue.front());
        a_queue.pop();
    }
}

问题是我的 CPU 使用率非常高,这似乎是 worker 无事可做时自旋锁的结果。我尝试使用互斥量,但我需要主线程在队列中没有任何内容时锁定它(当然这不可能发生)。有什么替代方法可以防止这种情况发生?

最佳答案

下面的代码是我之前在别处学到的。它是一个阻塞队列工具。线程可以安全地将元素放入队列,如果一个线程试图在队列为空时从队列中取出元素,它将被阻塞,直到其他线程将元素放入队列。希望对你有帮助

#include <queue>
#include <cassert>
#include <mutex>
#include <condition_variable>
#include <thread>
template<typename T>
class BlockingQueue
{
private:
    std::mutex _mutex;
    std::condition_variable _condvar;
    std::queue<T> _queue;
public:
    BlockingQueue(): _mutex(),_condvar(),_queue()
    {

    }
    BlockingQueue(const BlockingQueue& rhs) = delete;
    BlockingQueue& operator = (const BlockingQueue& rhs) = delete;

    void Put(const T& task)
    {
        {
            std::lock_guard<std::mutex> lock(_mutex);
            _queue.push(task);
        }
        _condvar.notify_all();
    }

    T Take()
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _condvar.wait(lock,[this]{return !_queue.empty(); });
        assert(!_queue.empty());
        T front(std::move(_queue.front()));
        _queue.pop();

        return front;
    }

};

关于c++ - 在不使用自旋锁的情况下在空队列上暂停线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33706332/

相关文章:

javascript - 这个速记运算符是怎么回事?

java - 你如何在不给别人源代码的情况下共享 Java 函数?

c++ - 使用动态链接库管理堆

java - 使用 Semaphore 和 acquire(int) 的 Java 代码中的死锁

c# - Rx.NET GroupByUntil 组终止,等待线程完成

performance - 矩阵乘法有多昂贵?

javascript - Object.keys() 复杂性?

c++ - 使用 Pro*C,如何使用带有构造函数的 C++ 结构,在 EXEC SQL BEGIN DECLARE SECTION 中复制构造函数

c++ - 如何同时运行两个线程? Qt C++

.net - 如何通过 .NET 中的线程传播 tcplistener 传入连接?