首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么将条件写入转换为无条件写入而不是线程安全优化?

为什么将条件写入转换为无条件写入而不是线程安全优化?
EN

Stack Overflow用户
提问于 2014-06-29 20:07:27
回答 4查看 322关注 0票数 4

在谈到并发性和C++11内存模型时,Herb给出了非法优化的例子。

http://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Herb-Sutter-atomic-Weapons-2-of-2

从幻灯片第17分钟开始:

代码语言:javascript
运行
复制
void f(vector<widget>& v) {
    if(v.length()>0) xMutex.lock();
    for(int i = 0; i < v.length(); ++i)
        ++x;                                  // write is conditional
    if(v.length()>0) xMutex.unlock();
}

“一个很有可能(如果有很大缺陷的)中央回路的转换:”

代码语言:javascript
运行
复制
r1 = x;
for(int i = 0; i < v.length(); ++i)
    ++r1;                                     // oops: write is not conditional
x = r1;

他解释说:"...this写是没有条件的,即使doOptionalWork是假的,它也会在每次执行时发生,这会注入一个不受互斥锁保护的写入,从而注入一个竞赛……“

为什么他说发明的写不受互斥锁的保护?我理解如下所描述的全部转换。

代码语言:javascript
运行
复制
// "optimized" version 1
void f(vector<widget>& v) {
    if(v.length() > 0) xMutex.lock()
    r1 = x;
    for(int i = 0; i < v.length(); ++i)
        ++r1;
    x = r1;
    if(v.length() > 0) xMutex.unlock();
}

但也有可能是这个。

代码语言:javascript
运行
复制
// "optimized" version 2
void f(vector<widget>& v) {
    if(v.length() > 0) xMutex.lock()
    r1 = x;
    for(int i = 0; i < v.length(); ++i)
        ++r1;
    if(v.length() > 0) xMutex.unlock();
    x = r1;
}

很明显,版本2不是线程安全,但我不确定版本1。版本1线程安全吗?如果在游戏中没有其他写到x的行怎么办?

刚才我开始输入“v.length()是0还是它不是.”意识到在一个多线程的世界里,即使是重言片语也会让我失望。我不知道从哪里开始推理这件事。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-06-29 20:12:10

只有当向量中有某种东西时,才使用互斥。在两个空向量上同时运行此方法会导致数据竞争,因为我们根本没有锁定,但是我们写到x。

票数 5
EN

Stack Overflow用户

发布于 2014-06-29 20:15:34

假设有另一个线程执行以下代码:

代码语言:javascript
运行
复制
xMutex.lock()
++x;
xMutex.unlock();

如果上述代码与(转换的)函数f同时执行,则x的增量可能会丢失,尽管在源代码级别上这是不可能的。

票数 2
EN

Stack Overflow用户

发布于 2014-06-29 20:44:08

mutex. lock()函数调用是锁互斥对象的方法。互斥锁是一个互斥锁,只允许一个调用方调用lock()并返回。订阅呼叫者会阻塞,等待原始呼叫者呼叫unlock()

它是“相互排斥的”,因为只允许一个线程获得锁。

这是互斥的定义。

在您发布的代码中,第二个块没有用lock()unlock()调用包装增量循环。

这意味着调用更改循环中修改的变量的函数的两个线程将相互执行。一个可以在紧接(或之后)之前写入变量,另一个循环则读取该变量。代码期望变量与函数一致,因此函数的行为将是不正确的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24479803

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档