Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 访问共享内存进行读取时锁定_C++_C_Multithreading - Fatal编程技术网

C++ 访问共享内存进行读取时锁定

C++ 访问共享内存进行读取时锁定,c++,c,multithreading,C++,C,Multithreading,如果访问共享内存是为了只读,要检查If()块的条件,是否仍应锁定互斥锁?例如 mutex_lock(); if (var /* shared memory */) { } mutex_unlock(); 这里是否需要锁定以及良好做法?如果您正在读取的变量可以同时写入,那么是的,您应该获得互斥锁 只有编译器为您提供了必要的原语,您才能以原子方式阅读它;这可能是C11和C++11附带的原子特性,也可能是编译器提供的其他语言扩展。然后,您可以将互斥体获取移动到条件中,但如果您等到测试完成后才获

如果访问共享内存是为了只读,要检查
If()
块的条件,是否仍应锁定互斥锁?例如

mutex_lock();

if (var /* shared memory */) {

}

mutex_unlock();

这里是否需要锁定以及良好做法?

如果您正在读取的变量可以同时写入,那么是的,您应该获得互斥锁

只有编译器为您提供了必要的原语,您才能以原子方式阅读它;这可能是C11和C++11附带的原子特性,也可能是编译器提供的其他语言扩展。然后,您可以将互斥体获取移动到条件中,但如果您等到测试完成后才获取互斥体,则其他人可能会在您测试互斥体和您获取互斥体之间对其进行更改:

if (example) {
    // "example" variable could be changed here by another thread.

    mutex_lock();

    // Now the condition might be false!

    mutex_unlock();
}

因此,我建议在条件之前获取互斥体,除非分析已经确定互斥体获取是一个瓶颈。(如果被测变量大于CPU寄存器(例如,32位CPU上的64位数字),那么您甚至无法在没有其他原子获取或比较原语的情况下延迟互斥体获取。)

挑剔的说法:“使用定义的行为读取互斥体”并不完全正确。根据C++11标准,在数据竞争中读取非原子数据返回的值是未定义的。(2011之前的C++和C规范没有定义多线程程序的语义。):变量也需要安装到一个CPU登记器中,并根据您的体系结构和编译器的规则进行调整,以便能够预测未定义的值可能是什么。@WanderingLogic-您必须具有适当的屏障以确保缓存得到更新,并且必须具有适当的编译器屏障以防优化时的代码移动。简言之:如果您没有使用原子类型,请不要尝试以原子方式处理某些事情。@WanderingLogic,我不会称之为吹毛求疵。答案的这一部分真是糟糕的建议。尝试这些技巧而不真正了解一切(这些东西是如何工作的,架构的细节)可能会导致很难找到的bug。我已将此答案标记为社区wiki——请随意将这些建议编辑到答案中。从这种根本性的改变中获得声誉对我来说是不公平的。这并不能回答这个问题,这完全是关于reading.Off-topic的,但是使用RAII风格的
lock
类来锁定互斥锁是一个非常好的主意,它可以在其析构函数中解锁互斥锁,就像
std::lock\u guard
所做的那样。否则,提前返回或抛出异常可能会使其永远锁定。