C++:条件变量-这个youtube演示中有错误吗
C++: Condition Variable - Is there a mistake in this youtube demo?
Youtube详细信息
我一直在浏览youtube,试图发展我对C++多线程支持互斥和条件变量的理解。
我偶然看到这个视频跳到时间6:30查看我当前正在查看的内容。(一页代码。(
- https://www.youtube.com/watch?v=eh_9zUNmTig
我相信代码中有一个错误,但我想检查一下。也可能是我什么都不懂。
问题
作者指出std::unique_lock
在创建互斥锁时会锁定互斥锁。这意味着没有必要调用
unique_lock<mutex> lock(m)
lock.lock(); // this is wrong, because unique_lock already locked the mutex
在创建CCD_ 2对象之后。
我假设,尽管我不确定,unique_lock
将在销毁时释放互斥锁。(超出范围时为阿卡。(
也可以通过调用手动解锁吗
lock.unlock()
从文档中看,似乎没有这样的解锁功能。因此看起来unique_lock
和scoped_lock
是一样的?但是,我再次假设事实并非如此,我还缺少一些其他信息。
继续作者有一个函数,看起来像这样:
void addMoney(int money)
{
std::lock_guard<mutex> lg(m); // lock_guard being used interchangably with unique_lock - why?
balance += money; // adding to global variable
cv.notify_one(); // error here
// the lock_guard is still in scope
// the mutex is still locked
// calling notify_one() may cause the sleeping thread to wake up
// check if the mutex is still locked (which it might be if the
// destructor for lg hasn't finished running)
// and then go back to sleep
// meaning this line of code may have no effect
// it is undefined behaviour
}
我已经说明了我认为哪里有错误。我认为这个函数会导致未定义的行为,因为lock_guard
仍然在作用域中,因此互斥可能被锁定。
实际上这是一个竞赛条件:
- 如果
addMoney()
在其他函数开始之前结束,我们就可以了 - 如果另一个函数
withdrawMoney()
在addMoney()
退出之前检查锁定(cv.wait()
(,则程序中断,并保持锁定状态
为了完整性,这里有另一个函数:
void withdrawMoney(int money)
{
std::unique_lock<mutex> ul(m); // unique_lock instead of scoped_lock? why?
cv.wait(ul, []{return balance != 0;});
// some more stuff omitted
}
摘要
我提出了几点
- 最重要的是比赛条件
- 次要的是,为什么两个不同的东西(
lock_guard
和unique_lock
(被用来做看起来的事情(执行相同的功能(
该注释
// calling notify_one() may cause the sleeping thread to wake up
// check if the mutex is still locked (which it might be if the
// destructor for lg hasn't finished running)
// and then go back to sleep
不正确。这里有两种独立的控制机制:条件变量和互斥。在一个条件变量的通知中醒来,简单地说,就是醒来。唤醒后,线程阻塞等待互斥。当调用notify_one()
的线程释放互斥体时,被阻塞的线程(或者可能是其他线程,但最终是被阻塞的螺纹(获得互斥体并继续执行。它不会返回到等待条件变量。
有关std::unique_lock与std::lock_guard的更多解释,请参阅此问题。
在互斥锁仍然被锁定的情况下发送通知时没有未定义的行为。它可能会导致不必要的线程切换,尤其是在接收线程具有更高优先级的情况下,但这只是一个小的性能打击。也不需要锁定互斥来发送通知,因此函数可以写成:
void addMoney(int money)
{
{
std::lock_guard<mutex> lg(m);
balance += money;
}
cv.notify_one();
}
您必须确保条件的资源在更改和检查时受到保护。
- 我的代码中有错误吗?使用BGI图形的C++代码对我不起作用
- 我的代码中有错误,未声明的标识符
- C++ LeetCode #377 的 DP 解决方案中,此代码是否有错误?
- 试图建立银行管理系统,但有错误
- 我试图创建临时对象的方式有错误吗
- 我的随机生成器是否不工作,或者我决定人/骨架是否击中对手的方式是否有错误
- 我在OpenCV中有错误的"approxPolyDP(ROI_Vertices, ROI_Poly, 1.0, true)"
- 我在这个 C++ 代码上有错误吗?
- 是视觉C++优化器错误还是我的代码中有错误?
- 为什么一个简单的C++程序会有错误的结果?是 #define 引起的吗?
- 对此有错误
- C :数据文件有错误:预期的无限制ID
- 一个带有参数的程序,为什么此程序有错误的答案
- 仅使用boost.datetime在Windows上有错误
- 使用向量循环时,是否有错误
- Microsoft Visual Studio发现我所有的CUDA设备端函数都有错误
- 继承默认构造函数在 gcc 中失败并在 clang 中工作,哪个有错误?
- 为什么有错误未定义_getws_s
- 在快速排序程序中有错误
- C - 检查CIN是否有错误