首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如果使用EventWaitHandel,从一个线程读取另一个线程时,是否为一个线程分配了“线程安全”变量?

如果使用EventWaitHandel,从一个线程读取另一个线程时,是否为一个线程分配了“线程安全”变量?
EN

Stack Overflow用户
提问于 2014-02-21 08:56:42
回答 2查看 76关注 0票数 0

如果我在一个线程上创建一个变量,然后使用ManualResetEventWaitOne()方法阻塞,直到另一个线程为同一个变量分配一个值并向EventWaitHandel发送信号。当我在第一个线程上读取变量时,我保证总是得到另一个线程分配的值吗?

(我担心我无法从CPU缓存中获得值,因为据我所知,我还没有使用任何内存屏障)。

例如:

代码语言:javascript
运行
复制
var str = "multi-threading is hard!";
var mre = new ManualResetEvent(false);
Task.Factory.StartNew(() => 
    {
        str = Console.ReadLine();
        mre.Set();
    ));
mre.WaitOne();
Console.WriteLine(str);
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-02-21 09:06:37

这些指令不会被重新排序,这意味着在生成线程上,字段分配总是在句柄发出信号之前发生,而在消费线程上,字段总是在句柄发出信号后被读取。

如果这两对指令中的任何一条可以重新排序(例如,如果第二个线程可以在句柄发出信号之前读取字段),那么您将看不到正确的值。

WaitOne()引入了一个隐式内存屏障,为您提供了所需的获取释放语义。

Brian和Hans列出了.NET框架中引入隐式内存屏障的几个类的列表:记忆屏障发生器

更多信息:获取和发布语义 / 获取和释放围栏

票数 1
EN

Stack Overflow用户

发布于 2014-02-21 09:03:11

您的变量是一个捕获的变量,即编译器将这个局部变量转换为编译器生成的类的字段,因为您在lambda表达式中使用它。Afaik,这些编译器生成的字段没有标记为volatile,因此可以缓存它们。

编辑:实际上,字段是不稳定的。

您可以通过编写自己的类来防止缓存,这样编译器就不必创建缓存。然而,这当然妨碍了代码的简洁性。

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

https://stackoverflow.com/questions/21929644

复制
相关文章

相似问题

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