How can I decrease the possibility of the producer(i.e. main thread in the code snippet code below) acquiring the lock whereas the consumer(i.e. wait thread) could not get the lock? It is would be better if you could tell me a method to avoid it. I don't think it is a good idea to use std::thread::sleep_for
or std::thread::yield
. And I have done some test and found that there is no effect when using std::thread::yield
.
I have thought about it for a long time, I would be grateful to have some help with this question.
If you run the code snippet, you may see such output:
Waiting...
test
Notifying falsely...
Notifying true change...
Notifying true change...
Notifying true change...
Notifying true change...
Notifying true change...
Notifying true change...
(**many many such output**)
Notifying true change...
test
...finished waiting. i == 1
Here is the related code snippet(check https://godbolt.org/z/9dwDJN):
#include <iostream>
#include <condition_variable>
#include <thread>
#include <chrono>
std::condition_variable cv;
std::mutex cv_m;
int i = 0;
bool done = false;
void waits()
{
std::unique_lock<std::mutex> lk(cv_m);
std::cout << "Waiting... \n";
cv.wait(lk, []{std::cout<<"test"<<std::endl; return i == 1;});
std::cout << "...finished waiting. i == 1\n";
done = true;
}
void signals()
{
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Notifying falsely...\n";
cv.notify_one(); // waiting thread is notified with i == 0.
// cv.wait wakes up, checks i, and goes back to waiting
std::unique_lock<std::mutex> lk(cv_m);
i = 1;
while (!done)
{
std::cout << "Notifying true change...\n";
lk.unlock();
cv.notify_one(); // waiting thread is notified with i == 1, cv.wait returns
//std::this_thread::sleep_for(std::chrono::seconds(1)); // I don't think it is good method.
//std::this_thread::yield(); //Maybe, this does not work.
lk.lock();
}
}
int main()
{
std::thread t1(waits), t2(signals);
t1.join();
t2.join();
}
Aucun commentaire:
Enregistrer un commentaire