含义std::互斥锁解锁与锁同步以重新获取
Implications std::mutex unlock synchronizes with lock to reacquiring
回答完这个问题后,有一件事再次困扰我,让我发疯:
如果一个线程_1当前正在尝试锁定一个互斥锁,而另一个线程_2解锁了这个互斥锁,那么在线程_2再次尝试锁定它之前,是否可以保证线程_1会获得互斥锁。
为了确保当前试图锁定,我假设std::condition_variable::wait
与std::mutex::lock
具有等效部分,而不仅仅是while(try_lock())
我认为答案是否定的,因为std::mutex
实现的调度不同。但我不确定,尽量不做一个名誉妓女,但是,
- 这个问题没有当前试图锁定
- 这个问题澄清了解锁/锁定与部分同步,但没有说明这个一般问题
我只是想确定一下。也许我有点偏执。
演示代码:
#include <thread>
#include <atomic>
#include <mutex>
#include <condition_variable>
#include <cassert>
std::mutex lock;
std::condition_variable ensure_in_lock;
std::atomic<int> invariant = 1;
void thread_1(){
while (true){
std::unique_lock<std::mutex> ul(lock);
invariant++;
ensure_in_lock.wait(ul);
invariant++;
}
}
void thread_2(){
while (true){
lock.lock();
assert(invariant > 0); //<- This should be, in theory, able to break, shouldn't it?!
ensure_in_lock.notify_all();
lock.unlock();
invariant--;
}
}
int main(void)
{
std::thread t1(thread_1);
/*
//make sure t1 really had started like with thread_once or pratically with this
std::this_thread::sleep_for(std::chrono::seconds(1));
*/
std::thread t2(thread_2);
while (true);
return 0;
}
如果一个线程_1当前正试图锁定一个互斥体,而另一个线程_2解锁了该互斥体,那么在线程_2再次尝试锁定互斥体之前,是否可以保证线程_1会获得该互斥体。
不仅没有保证,而且这样的保证将要求实现一个最可怕的实现,最大化上下文切换,而不是最小化它们。如果一个线程可以继续运行,那么您希望让它继续运行并用完它的时间片。您不希望在两个线程之间不断切换,让每个线程的进度都有微小的增量。
锁的好处之一是,它们倾向于取消对争用线程的调度,允许线程运行更长的时间,而不会因争用而导致性能损失。这样的交错要求将否定这种益处。
相关文章:
- 如何在新的派生对象中获取基本对象的数据?
- 获取“将返回值分配给新变量”的警告和输出是内存地址
- 如何在C++程序中打开一个新的cmd.exe并获取其句柄
- 如何获取两个列表的公共元素并将其存储在新列表中而不会重复
- 我可以获取在重载的新运算符中使用新运算符的对象类型吗?
- 写入文件时需要帮助获取新行
- 在新数组中获取随机值
- 如何获取wxGrid中移动列的新索引
- C++ std::map 如何在每次调用类对象时获取新的 map 对象
- 使用getchar()获取字符并将其保存到每次C 的新行中的文件中
- EntityX-获取添加到系统中的新实体
- OCI在不知道表结构的情况下获取获取的数据
- 新的C++ Mongo 驱动程序:如何查看类型和如何获取字符串值
- 如何在输入新值后获取 qtreewidgetitem 的新值
- 如何获取绘制点的新坐标
- 获取错误:新声明符中的表达式必须具有整型或枚举类型C++
- 如何获取新的数组值?C++
- 没有 /resetsettings 就无法运行 VS 2015 社区;在打开新项目时获取 CANTLOAD 库,并在新.cpp文件上崩溃
- 如何获取当前持有的变量类型,并定义该类型的新变量
- Qt中新的获取链接器和Makefile错误