简单生产者& amp;消费者

时间:2017-12-20 14:44:57

标签: c++ c++11 producer-consumer unique-lock

我编写了一个非常简单的基于C ++ 11注释的生产者/消费者,并且无法弄清楚为什么unique_lock()在超出范围时不会释放锁。

struct Message{
Message(int x):data(x){cout<<"+";}
int data;
};


queue<Message*> g_queue;
condition_variable cv;
mutex m;

void consumer()
{
    do {
        unique_lock<mutex> lck {m};
        cv.wait(lck, [&](){return !g_queue.empty();});
        cout<<"Notified...";
        auto& obj = g_queue.front();
        std::cout<<obj->data;
        g_queue.pop();
        cout<<".";
        lck.unlock(); -----(1)
    } while(1);

}

void producer() 
{
    while(true){
            unique_lock<mutex> lck {m};
            Message msg{5};
            cout<<"Queue size:"<<g_queue.size()<<'\n';
            g_queue.push(&msg);
            cv.notify_one();
            lck.unlock(); -------(2)
            cout<<"-"<<'\n';
            this_thread::sleep_for(std::chrono::milliseconds{2000});
    }
}

并将其用作: -

    thread Q(&consumer);
    thread P(&producer);
    P.join();
    Q.join();

输出结果为: -

+Queue size:0
-Notified...
5.+Queue size:0
-Notified...5
.+Queue size:0
-Notified...5

从技术上讲,是的,生产者需要告诉消费者我已做好准备,消费者需要让生产者知道发送更多数据。我不清楚使用什么,条件变量是这样做还是unique_lock这样做。

准确地说,为什么我需要(1)和(2)当范围可以释放锁

==编辑== 以下是经过编辑的代码,工作正常,

void consumer()
{
    do {
        unique_lock<mutex> lck {m};
        cv.wait(lck, [&](){return !g_queue.empty();});
        cout<<"Notified...";
        auto& obj = g_queue.front();
        std::cout<<obj->data;
        g_queue.pop();
        cout<<".";
    } while(1);

}

Message msg{5};
void producer() 
{
    while(true){
            unique_lock<mutex> lck {m};
            cout<<"Queue size:"<<g_queue.size()<<'\n';
            g_queue.push(&msg);
            cv.notify_one();
            cout<<"-"<<'\n';
    }
}

现在,如果我希望在生产者或消费者中,如果睡眠有风险,我该如何引入一点油门?

1 个答案:

答案 0 :(得分:0)

不确定这里还有一个问题,但是一种限制解决方案是允许队列在生产者中增长到最大大小。当队列达到此大小时,生成器将等待不同的条件变量。当队列低于特定大小时,消费者发出第二个条件变量的信号。 (后者的大小可能稍微小于给出一些滞后的最大值。)等待这个新条件变量的谓词是g_queue.size() >= max_size