简单生产者和消费者的unique_lock困难

Difficulty with unique_lock in simple Producer & Consumer

本文关键字:unique lock 困难 消费者 简单生产 生产者 简单      更新时间:2023-10-16

我已经写了一个非常简单的生产者/消费者,基于C 11 Notes,并且无法弄清楚为什么唯一的_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';
    }
}

现在,如果我想在生产者或消费者中,如果睡眠有风险,我该如何介绍一些油门?

不确定这里仍然有一个问题,但是限制的一种解决方案是具有最大尺寸,允许队列在生产者中生长。当队列达到这一尺寸时,生产者会在其他条件变量上等待。当队列降至一定尺寸以下时,消费者向第二个条件变量发出信号。(后者的大小可能比最大滞后的最大值要小。)等待此新条件变量的谓词是g_queue.size() >= max_size