C++ 11 개의 노트를 기반으로 작성된 매우 간단한 프로듀서/소비자를 작성했으며 unique_lock()이 범위를 벗어날 때 잠금을 해제하지 않는 이유를 파악할 수 없습니다. 출력은단순한 생산자 및 소비자의 unique_lock에 대한 어려움
thread Q(&consumer);
thread P(&producer);
P.join();
Q.join();
: - : -로
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});
}
}
그리고 그것을 사용
+Queue size:0
-Notified...
5.+Queue size:0
-Notified...5
.+Queue size:0
-Notified...5
그래서 기술적으로, 그래, 프로듀서 내가 준비하는 소비자에게 필요하고 소비자에 필요 Producer가 더 많은 데이터를 전송하도록 알려줍니다. 나는 무엇을 사용해야하는지 명확하지 않다. 조건 변수가 이것을하는지, 또는 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) 필요하지 않습니다. 그렇지 않으면'생산자'가 자고있는 동안 자물쇠를 잡아서 '소비자'가 굶어 버리기 때문에 (2)가 필요합니다. 또한, 프로그램은 정의되지 않은 동작을 보여줍니다 : 로컬 변수에 대한 포인터로'g_queue'를 채 웁니다.이 포인터는 포인터가 검색되고 참조 해제 될 때 아주 잘 파괴 될 수 있습니다. –
예, 이해합니다. 굶주림은 내가 (1)과 (2)를 모두 제거하면서 달릴 때 볼 수있는 행동의 원인입니다. 그래서 sleep 문을 제거하고 출력에서 문맥 전환을 볼 수있었습니다. 또한 지역 변수 문제를 이해하고이를 코드에서 수정했습니다. – cpp11dev