首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >原始同步原语--安全吗?

原始同步原语--安全吗?
EN

Stack Overflow用户
提问于 2009-04-23 18:15:46
回答 5查看 919关注 0票数 4

在受限的设备上,我经常发现自己在两个线程之间使用两个bool“伪造”锁。每个线程只能由一个线程读取,并且只能由另一个线程写入。我的意思是:

代码语言:javascript
复制
bool quitted = false, paused = false;
bool should_quit = false, should_pause = false;

void downloader_thread() {
    quitted = false;
    while(!should_quit) {
        fill_buffer(bfr);
        if(should_pause) {
            is_paused = true;
            while(should_pause) sleep(50);
            is_paused = false;
        }
    }
    quitted = true;
}

void ui_thread() {
    // new Thread(downloader_thread).start();
    // ...
    should_pause = true;
    while(!is_paused) sleep(50);
        // resize buffer or something else non-thread-safe
    should_pause = false;
}

当然,在PC上我不会这样做,但在受限的设备上,读取bool值似乎比获取锁要快得多。当然,当需要更改缓冲区时,我会牺牲较慢的恢复速度(参见"sleep(50)")。

问题是--它是完全线程安全的吗?或者有没有隐藏的陷阱,我需要注意的时候,像这样的假锁?或者我根本不应该这样做?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2009-04-23 18:20:20

除非您详细了解设备的内存体系结构以及编译器生成的代码,否则此代码是不安全的。

仅仅因为它看起来会工作,并不意味着它会工作。“受限”设备,如非受限类型,正变得越来越强大。例如,我不会打赌不能在手机中找到双核CPU。这意味着我不敢打赌上面的代码会工作。

票数 5
EN

Stack Overflow用户

发布于 2009-04-23 23:03:53

使用布尔值在线程之间进行通信可以按预期工作,但确实存在两个隐藏的陷阱,如this blog post by Vitaliy Liptchinsky中所述

缓存一致性

CPU并不总是从RAM中获取内存值。芯片上的快速内存缓存是CPU设计人员用来绕过Von Neumann bottleneck的诀窍之一。在某些多CPU或多核架构(如英特尔的Itanium)上,这些CPU缓存不是共享的,也不会自动保持同步。换句话说,如果你的线程运行在不同的CPU上,那么你的线程可能会看到相同内存地址的不同值。

为了避免这种情况,您需要将变量声明为volatile (C++C#或do explicit volatile read/writes ),或者使用锁定机制。

编译器优化

如果涉及多个线程,编译器或JITter可能会执行不安全的优化。有关示例,请参阅链接的博客帖子。同样,您必须使用volatile关键字或其他机制来通知编译器。

票数 6
EN

Stack Overflow用户

发布于 2009-04-23 18:22:24

关于睡眠调用,你总是可以只做睡眠(0)或等效的调用,它会暂停你的线程,让下一个线程轮流。

关于其余部分,如果你知道你的设备的实现细节,这是线程安全的。

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

https://stackoverflow.com/questions/782912

复制
相关文章

相似问题

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