If a thread that is blocked on a std::condition_variable is notified, but the lock on the associated mutex has not been released what would be result?

huangapple go评论53阅读模式
英文:

If a thread that is blocked on a std::condition_variable is notified, but the lock on the associated mutex has not been released what would be result?

问题

以下是您要翻译的代码部分:

Is it clear what would happen if a thread blocked on a std::condition_variable receives a notification but the lock on the associated mutex is not yet released, and the lock will be released 10 seconds later? Would the thread wait for the lock to be released or is the situation undefined?
I added a 15seconds sleep on purpose to make the lock unavailable during that time to see how waiting thread will be doing. It is doing OK but just wanted to be sure about it.

#include <iostream>
#include <condition_variable>
#include <thread>
#include <chrono>

struct SharedResource
{
	SharedResource() :
		cv_mutex(), cv(), counter(0)
	{

	}

	/*
	This mutex is used for three purposes:
	1) to synchronize accesses to counter
	2) to synchronize accesses to std::cerr
	3) for the condition variable cv
	*/
	std::mutex cv_mutex;
	std::condition_variable cv;
	int counter;
};

void waits(SharedResource& sharedRes)
{
	std::unique_lock<std::mutex> lk(sharedRes.cv_mutex);
	std::cerr << "Waiting... \n";
	while (sharedRes.counter != 1) 
	{
		sharedRes.cv.wait_for(lk,3s);
		std::cerr << "Thread ID: " << std::this_thread::get_id() << " wakes up every 3 seconds.\n";
	}
	std::cerr << "...finished waiting." << "counter: " << sharedRes.counter << std::endl;
} //The lk object will be unlocked after this scope ends.

void signals(SharedResource& sharedRes)
{
	std::this_thread::sleep_for(std::chrono::seconds(1));
	{
		std::lock_guard<std::mutex> lk(sharedRes.cv_mutex);
		std::cerr << "Notifying...\n";
	} // The lk object will be unlocked after this scope ends.
	sharedRes.cv.notify_all();

	std::this_thread::sleep_for(std::chrono::seconds(6));

	{
		std::lock_guard<std::mutex> lk(sharedRes.cv_mutex);
		sharedRes.counter = 1;
		std::cerr << "Notifying again...\n";

		sharedRes.cv.notify_all();
		std::this_thread::sleep_for(std::chrono::seconds(15));

	}// The lk object will be unlocked after this scope ends.
}

int main()
{
	SharedResource sharedRes;

	std::thread
		t1(waits, std::ref(sharedRes)),
		t2(signals, std::ref(sharedRes));
	t1.join();
	t2.join();
}

如果您有任何其他问题或需要进一步的帮助,请随时告诉我。

英文:

Is it clear what would happen if a thread blocked on a std::condition_variable receives a notification but the lock on the associated mutex is not yet released, and the lock will be released 10 seconds later? Would the thread wait for the lock to be released or is the situation undefined?
I added a 15seconds sleep on purpose to make the lock unavailable during that time to see how waiting thread will be doing. It is doing OK but just wanted to be sure about it.

#include &lt;iostream&gt;
#include &lt;condition_variable&gt;
#include &lt;thread&gt;
#include &lt;chrono&gt;
struct SharedResource
{
SharedResource() :
cv_mutex(), cv(), counter(0)
{
}
/*
This mutex is used for three purposes:
1) to synchronize accesses to counter
2) to synchronize accesses to std::cerr
3) for the condition variable cv
*/
std::mutex cv_mutex;
std::condition_variable cv;
int counter;
};
void waits(SharedResource&amp; sharedRes)
{
std::unique_lock&lt;std::mutex&gt; lk(sharedRes.cv_mutex);
std::cerr &lt;&lt; &quot;Waiting... \n&quot;;
while (sharedRes.counter != 1) 
{
sharedRes.cv.wait_for(lk,3s);
std::cerr &lt;&lt; &quot;Thread ID: &quot; &lt;&lt; std::this_thread::get_id() &lt;&lt; &quot; wakes up every 3 seconds.\n&quot;;
}
std::cerr &lt;&lt; &quot;...finished waiting.&quot; &lt;&lt; &quot;counter: &quot; &lt;&lt; sharedRes.counter &lt;&lt; std::endl;
} //The lk object will be unlocked after this scope ends.
void signals(SharedResource&amp; sharedRes)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
{
std::lock_guard&lt;std::mutex&gt; lk(sharedRes.cv_mutex);
std::cerr &lt;&lt; &quot;Notifying...\n&quot;;
} // The lk object will be unlocked after this scope ends.
sharedRes.cv.notify_all();
std::this_thread::sleep_for(std::chrono::seconds(6));
{
std::lock_guard&lt;std::mutex&gt; lk(sharedRes.cv_mutex);
sharedRes.counter = 1;
std::cerr &lt;&lt; &quot;Notifying again...\n&quot;;
sharedRes.cv.notify_all();
std::this_thread::sleep_for(std::chrono::seconds(15));
}// The lk object will be unlocked after this scope ends.
}
int main()
{
SharedResource sharedRes;
std::thread
t1(waits, std::ref(sharedRes)),
t2(signals, std::ref(sharedRes));
t1.join();
t2.join();
}

答案1

得分: 2

如果一个在std::condition_variable上被阻塞的线程被通知,但与之关联的mutex上的锁尚未释放,结果将如何?

它将继续wait / wait_for,直到能重新获取锁。

std::condition_variable::waitwait_for返回(无论出于何种原因),锁再次被持有,因此您不必担心这一点。

甚至可以在没有收到任何通知的情况下从wait中返回(虚假唤醒)- 但无论如何,当调用返回时锁都会被重新获取。

英文:

> If a thread that is blocked on a std::condition_variable is notified, but the lock on the associated mutex has not been released what would be result?

It will continue to wait / wait_for until it can reacquire the lock.

When std::condition_variable::wait and wait_for returns (for whatever reason), the lock is held again, so you don't have to worry about that.

It can even return from wait without having gotten any notifications (spurious wake-ups) - but, no matter what, the lock is reacquired when the call returns.

huangapple
  • 本文由 发表于 2023年2月14日 01:17:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/75439155.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定