【发布时间】:2017-08-03 14:28:25
【问题描述】:
有一个新的实验性功能(可能是 C++20),即“同步块”。该块提供了对一段代码的全局锁定。以下是来自cppreference的示例。
#include <iostream>
#include <vector>
#include <thread>
int f()
{
static int i = 0;
synchronized {
std::cout << i << " -> ";
++i;
std::cout << i << '\n';
return i;
}
}
int main()
{
std::vector<std::thread> v(10);
for(auto& t: v)
t = std::thread([]{ for(int n = 0; n < 10; ++n) f(); });
for(auto& t: v)
t.join();
}
我觉得这是多余的。上面的同步块和这个有什么区别:
std::mutex m;
int f()
{
static int i = 0;
std::lock_guard<std::mutex> lg(m);
std::cout << i << " -> ";
++i;
std::cout << i << '\n';
return i;
}
我在这里发现的唯一好处是我省去了使用全局锁的麻烦。使用同步块有更多优点吗?什么时候应该首选?
【问题讨论】:
-
不确定是否确实如此,但 cppreference 听起来第一个版本保证在第一个示例中按顺序打印,而 AFAIK 第二个版本则没有。
-
"虽然同步块在全局锁下执行,但实现应该检查每个块中的代码并使用乐观并发(由硬件事务内存在可用的情况下备份)以实现事务安全非事务安全代码的代码和最小锁定。"
-
@TheQuantumPhysicist、
std::lock_guard和std::mutex不是 C++ 语言的一部分:它们只是在库中定义的类。特别是,编译器无法知道mutex的含义——互斥操作如何与操作系统交互,或者它们对线程有什么影响。synchronized关键字在这方面会有很大不同。 -
不,优化不能移除显式锁;锁定有明显的副作用。
-
我明白了。谢谢你的解释。请在 SO 平台上提供答案。
标签: c++ multithreading transactional-memory