Is it possible for the notifying thread to lock before the notified thread's wait to lock?
Example code from std::condition_variable::notify_one.
My question is:
Is it possible for a notifying thread to lock, before the notified thread's wait
function to lock, since the notify
operation does not block current thread?
Code: (I delete the original comments)
#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, {return i == 1;}); //Waiting
std::cout << "...finished waiting. i == 1n";
done = true;
}
void signals()
{
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Notifying falsely...n";
cv.notify_one(); //Notifying
std::unique_lock<std::mutex> lk(cv_m);//Is it possible for this line to execute
//before cv.waits() in waits() tries to lock ?
i = 1;
while (!done)
{
std::cout << "Notifying true change...n";
lk.unlock();
cv.notify_one();
std::this_thread::sleep_for(std::chrono::seconds(1));
lk.lock();
}
}
int main()
{
std::thread t1(waits), t2(signals);
t1.join();
t2.join();
}
c++ multithreading order-of-evaluation
add a comment |
Example code from std::condition_variable::notify_one.
My question is:
Is it possible for a notifying thread to lock, before the notified thread's wait
function to lock, since the notify
operation does not block current thread?
Code: (I delete the original comments)
#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, {return i == 1;}); //Waiting
std::cout << "...finished waiting. i == 1n";
done = true;
}
void signals()
{
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Notifying falsely...n";
cv.notify_one(); //Notifying
std::unique_lock<std::mutex> lk(cv_m);//Is it possible for this line to execute
//before cv.waits() in waits() tries to lock ?
i = 1;
while (!done)
{
std::cout << "Notifying true change...n";
lk.unlock();
cv.notify_one();
std::this_thread::sleep_for(std::chrono::seconds(1));
lk.lock();
}
}
int main()
{
std::thread t1(waits), t2(signals);
t1.join();
t2.join();
}
c++ multithreading order-of-evaluation
2
Yes, it is possible to lock by notifying thread before the waiting one. But how does it make the code unsafe?
– bartop
Nov 13 '18 at 15:23
@bartop Yes, you are right.. It won't make the code unsafe even so. Btw, is there any rules that gurantee the execution order? Or it is simply undefined?
– Rick
Nov 13 '18 at 15:39
add a comment |
Example code from std::condition_variable::notify_one.
My question is:
Is it possible for a notifying thread to lock, before the notified thread's wait
function to lock, since the notify
operation does not block current thread?
Code: (I delete the original comments)
#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, {return i == 1;}); //Waiting
std::cout << "...finished waiting. i == 1n";
done = true;
}
void signals()
{
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Notifying falsely...n";
cv.notify_one(); //Notifying
std::unique_lock<std::mutex> lk(cv_m);//Is it possible for this line to execute
//before cv.waits() in waits() tries to lock ?
i = 1;
while (!done)
{
std::cout << "Notifying true change...n";
lk.unlock();
cv.notify_one();
std::this_thread::sleep_for(std::chrono::seconds(1));
lk.lock();
}
}
int main()
{
std::thread t1(waits), t2(signals);
t1.join();
t2.join();
}
c++ multithreading order-of-evaluation
Example code from std::condition_variable::notify_one.
My question is:
Is it possible for a notifying thread to lock, before the notified thread's wait
function to lock, since the notify
operation does not block current thread?
Code: (I delete the original comments)
#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, {return i == 1;}); //Waiting
std::cout << "...finished waiting. i == 1n";
done = true;
}
void signals()
{
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Notifying falsely...n";
cv.notify_one(); //Notifying
std::unique_lock<std::mutex> lk(cv_m);//Is it possible for this line to execute
//before cv.waits() in waits() tries to lock ?
i = 1;
while (!done)
{
std::cout << "Notifying true change...n";
lk.unlock();
cv.notify_one();
std::this_thread::sleep_for(std::chrono::seconds(1));
lk.lock();
}
}
int main()
{
std::thread t1(waits), t2(signals);
t1.join();
t2.join();
}
c++ multithreading order-of-evaluation
c++ multithreading order-of-evaluation
edited Nov 13 '18 at 15:46
Rick
asked Nov 13 '18 at 14:50
RickRick
1,563929
1,563929
2
Yes, it is possible to lock by notifying thread before the waiting one. But how does it make the code unsafe?
– bartop
Nov 13 '18 at 15:23
@bartop Yes, you are right.. It won't make the code unsafe even so. Btw, is there any rules that gurantee the execution order? Or it is simply undefined?
– Rick
Nov 13 '18 at 15:39
add a comment |
2
Yes, it is possible to lock by notifying thread before the waiting one. But how does it make the code unsafe?
– bartop
Nov 13 '18 at 15:23
@bartop Yes, you are right.. It won't make the code unsafe even so. Btw, is there any rules that gurantee the execution order? Or it is simply undefined?
– Rick
Nov 13 '18 at 15:39
2
2
Yes, it is possible to lock by notifying thread before the waiting one. But how does it make the code unsafe?
– bartop
Nov 13 '18 at 15:23
Yes, it is possible to lock by notifying thread before the waiting one. But how does it make the code unsafe?
– bartop
Nov 13 '18 at 15:23
@bartop Yes, you are right.. It won't make the code unsafe even so. Btw, is there any rules that gurantee the execution order? Or it is simply undefined?
– Rick
Nov 13 '18 at 15:39
@bartop Yes, you are right.. It won't make the code unsafe even so. Btw, is there any rules that gurantee the execution order? Or it is simply undefined?
– Rick
Nov 13 '18 at 15:39
add a comment |
1 Answer
1
active
oldest
votes
In answer to your title question, yes. It is possible that the signals
thread locks prior to the waits
thread. But in answer to your real question, no, this won't cause a deadlock.
Why?
Because further in the example the mutex is released by lk.unlock()
. At this unlock the waits
thread will have an opportunity to lock (then unlock again when waiting begins).
This loop continues until the wait
thread has signified it is completed with the done
boolean.
An example timing:
There are plenty of others, but in all cases the relevant objects and condition variables are protected by the mutex. You can't have data races or deadlocks. This example is sound.
Thank you Mr Fox. So the execution order of which is simply not guaranteed and I should not count on it right?
– Rick
Nov 13 '18 at 16:11
1
@Rick No it is not. That is why you should consider all of the possible orders to find if you can have data races or deadlocks.
– Fantastic Mr Fox
Nov 13 '18 at 16:17
Btw, I recheck the page of cppreference and notice that in the output section, it's writing "possible output", which may indirectly prove that. And in fact, the output cppreference shows and I get is : "the notifying thread lock first"...
– Rick
Nov 13 '18 at 16:19
1
@Rick, it can be worse then that as well. Read further intocondition_variable
you will find it can spuriously wake up for no reason at all. That's why you need the predicate (lambda in this case) that checks that the wait condition has actually been achieved. And you need the resources that the predicate uses to be protected by the mutex ...
– Fantastic Mr Fox
Nov 13 '18 at 16:24
1
@Rick You can make them here: sequencediagram.org As for the coment about waiting begins not being right, i am unsure qwhat you mean. It seems like you are saying the same thing that is in the timing diagram.
– Fantastic Mr Fox
Nov 14 '18 at 7:24
|
show 4 more comments
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53283632%2fis-it-possible-for-the-notifying-thread-to-lock-before-the-notified-threads-wai%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
In answer to your title question, yes. It is possible that the signals
thread locks prior to the waits
thread. But in answer to your real question, no, this won't cause a deadlock.
Why?
Because further in the example the mutex is released by lk.unlock()
. At this unlock the waits
thread will have an opportunity to lock (then unlock again when waiting begins).
This loop continues until the wait
thread has signified it is completed with the done
boolean.
An example timing:
There are plenty of others, but in all cases the relevant objects and condition variables are protected by the mutex. You can't have data races or deadlocks. This example is sound.
Thank you Mr Fox. So the execution order of which is simply not guaranteed and I should not count on it right?
– Rick
Nov 13 '18 at 16:11
1
@Rick No it is not. That is why you should consider all of the possible orders to find if you can have data races or deadlocks.
– Fantastic Mr Fox
Nov 13 '18 at 16:17
Btw, I recheck the page of cppreference and notice that in the output section, it's writing "possible output", which may indirectly prove that. And in fact, the output cppreference shows and I get is : "the notifying thread lock first"...
– Rick
Nov 13 '18 at 16:19
1
@Rick, it can be worse then that as well. Read further intocondition_variable
you will find it can spuriously wake up for no reason at all. That's why you need the predicate (lambda in this case) that checks that the wait condition has actually been achieved. And you need the resources that the predicate uses to be protected by the mutex ...
– Fantastic Mr Fox
Nov 13 '18 at 16:24
1
@Rick You can make them here: sequencediagram.org As for the coment about waiting begins not being right, i am unsure qwhat you mean. It seems like you are saying the same thing that is in the timing diagram.
– Fantastic Mr Fox
Nov 14 '18 at 7:24
|
show 4 more comments
In answer to your title question, yes. It is possible that the signals
thread locks prior to the waits
thread. But in answer to your real question, no, this won't cause a deadlock.
Why?
Because further in the example the mutex is released by lk.unlock()
. At this unlock the waits
thread will have an opportunity to lock (then unlock again when waiting begins).
This loop continues until the wait
thread has signified it is completed with the done
boolean.
An example timing:
There are plenty of others, but in all cases the relevant objects and condition variables are protected by the mutex. You can't have data races or deadlocks. This example is sound.
Thank you Mr Fox. So the execution order of which is simply not guaranteed and I should not count on it right?
– Rick
Nov 13 '18 at 16:11
1
@Rick No it is not. That is why you should consider all of the possible orders to find if you can have data races or deadlocks.
– Fantastic Mr Fox
Nov 13 '18 at 16:17
Btw, I recheck the page of cppreference and notice that in the output section, it's writing "possible output", which may indirectly prove that. And in fact, the output cppreference shows and I get is : "the notifying thread lock first"...
– Rick
Nov 13 '18 at 16:19
1
@Rick, it can be worse then that as well. Read further intocondition_variable
you will find it can spuriously wake up for no reason at all. That's why you need the predicate (lambda in this case) that checks that the wait condition has actually been achieved. And you need the resources that the predicate uses to be protected by the mutex ...
– Fantastic Mr Fox
Nov 13 '18 at 16:24
1
@Rick You can make them here: sequencediagram.org As for the coment about waiting begins not being right, i am unsure qwhat you mean. It seems like you are saying the same thing that is in the timing diagram.
– Fantastic Mr Fox
Nov 14 '18 at 7:24
|
show 4 more comments
In answer to your title question, yes. It is possible that the signals
thread locks prior to the waits
thread. But in answer to your real question, no, this won't cause a deadlock.
Why?
Because further in the example the mutex is released by lk.unlock()
. At this unlock the waits
thread will have an opportunity to lock (then unlock again when waiting begins).
This loop continues until the wait
thread has signified it is completed with the done
boolean.
An example timing:
There are plenty of others, but in all cases the relevant objects and condition variables are protected by the mutex. You can't have data races or deadlocks. This example is sound.
In answer to your title question, yes. It is possible that the signals
thread locks prior to the waits
thread. But in answer to your real question, no, this won't cause a deadlock.
Why?
Because further in the example the mutex is released by lk.unlock()
. At this unlock the waits
thread will have an opportunity to lock (then unlock again when waiting begins).
This loop continues until the wait
thread has signified it is completed with the done
boolean.
An example timing:
There are plenty of others, but in all cases the relevant objects and condition variables are protected by the mutex. You can't have data races or deadlocks. This example is sound.
edited Nov 13 '18 at 16:17
answered Nov 13 '18 at 15:51
Fantastic Mr FoxFantastic Mr Fox
18.6k1967131
18.6k1967131
Thank you Mr Fox. So the execution order of which is simply not guaranteed and I should not count on it right?
– Rick
Nov 13 '18 at 16:11
1
@Rick No it is not. That is why you should consider all of the possible orders to find if you can have data races or deadlocks.
– Fantastic Mr Fox
Nov 13 '18 at 16:17
Btw, I recheck the page of cppreference and notice that in the output section, it's writing "possible output", which may indirectly prove that. And in fact, the output cppreference shows and I get is : "the notifying thread lock first"...
– Rick
Nov 13 '18 at 16:19
1
@Rick, it can be worse then that as well. Read further intocondition_variable
you will find it can spuriously wake up for no reason at all. That's why you need the predicate (lambda in this case) that checks that the wait condition has actually been achieved. And you need the resources that the predicate uses to be protected by the mutex ...
– Fantastic Mr Fox
Nov 13 '18 at 16:24
1
@Rick You can make them here: sequencediagram.org As for the coment about waiting begins not being right, i am unsure qwhat you mean. It seems like you are saying the same thing that is in the timing diagram.
– Fantastic Mr Fox
Nov 14 '18 at 7:24
|
show 4 more comments
Thank you Mr Fox. So the execution order of which is simply not guaranteed and I should not count on it right?
– Rick
Nov 13 '18 at 16:11
1
@Rick No it is not. That is why you should consider all of the possible orders to find if you can have data races or deadlocks.
– Fantastic Mr Fox
Nov 13 '18 at 16:17
Btw, I recheck the page of cppreference and notice that in the output section, it's writing "possible output", which may indirectly prove that. And in fact, the output cppreference shows and I get is : "the notifying thread lock first"...
– Rick
Nov 13 '18 at 16:19
1
@Rick, it can be worse then that as well. Read further intocondition_variable
you will find it can spuriously wake up for no reason at all. That's why you need the predicate (lambda in this case) that checks that the wait condition has actually been achieved. And you need the resources that the predicate uses to be protected by the mutex ...
– Fantastic Mr Fox
Nov 13 '18 at 16:24
1
@Rick You can make them here: sequencediagram.org As for the coment about waiting begins not being right, i am unsure qwhat you mean. It seems like you are saying the same thing that is in the timing diagram.
– Fantastic Mr Fox
Nov 14 '18 at 7:24
Thank you Mr Fox. So the execution order of which is simply not guaranteed and I should not count on it right?
– Rick
Nov 13 '18 at 16:11
Thank you Mr Fox. So the execution order of which is simply not guaranteed and I should not count on it right?
– Rick
Nov 13 '18 at 16:11
1
1
@Rick No it is not. That is why you should consider all of the possible orders to find if you can have data races or deadlocks.
– Fantastic Mr Fox
Nov 13 '18 at 16:17
@Rick No it is not. That is why you should consider all of the possible orders to find if you can have data races or deadlocks.
– Fantastic Mr Fox
Nov 13 '18 at 16:17
Btw, I recheck the page of cppreference and notice that in the output section, it's writing "possible output", which may indirectly prove that. And in fact, the output cppreference shows and I get is : "the notifying thread lock first"...
– Rick
Nov 13 '18 at 16:19
Btw, I recheck the page of cppreference and notice that in the output section, it's writing "possible output", which may indirectly prove that. And in fact, the output cppreference shows and I get is : "the notifying thread lock first"...
– Rick
Nov 13 '18 at 16:19
1
1
@Rick, it can be worse then that as well. Read further into
condition_variable
you will find it can spuriously wake up for no reason at all. That's why you need the predicate (lambda in this case) that checks that the wait condition has actually been achieved. And you need the resources that the predicate uses to be protected by the mutex ...– Fantastic Mr Fox
Nov 13 '18 at 16:24
@Rick, it can be worse then that as well. Read further into
condition_variable
you will find it can spuriously wake up for no reason at all. That's why you need the predicate (lambda in this case) that checks that the wait condition has actually been achieved. And you need the resources that the predicate uses to be protected by the mutex ...– Fantastic Mr Fox
Nov 13 '18 at 16:24
1
1
@Rick You can make them here: sequencediagram.org As for the coment about waiting begins not being right, i am unsure qwhat you mean. It seems like you are saying the same thing that is in the timing diagram.
– Fantastic Mr Fox
Nov 14 '18 at 7:24
@Rick You can make them here: sequencediagram.org As for the coment about waiting begins not being right, i am unsure qwhat you mean. It seems like you are saying the same thing that is in the timing diagram.
– Fantastic Mr Fox
Nov 14 '18 at 7:24
|
show 4 more comments
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53283632%2fis-it-possible-for-the-notifying-thread-to-lock-before-the-notified-threads-wai%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
Yes, it is possible to lock by notifying thread before the waiting one. But how does it make the code unsafe?
– bartop
Nov 13 '18 at 15:23
@bartop Yes, you are right.. It won't make the code unsafe even so. Btw, is there any rules that gurantee the execution order? Or it is simply undefined?
– Rick
Nov 13 '18 at 15:39