的AutoResetEvent与布尔来停止一个线程 [英] AutoResetEvent vs. boolean to stop a thread

查看:252
本文介绍了的AutoResetEvent与布尔来停止一个线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个工作线程,我可以指示停止运行的对象。我可以用一个布尔或的AutoResetEvent实现这一点:

I have an object in a worker thread, which I can instruct to stop running. I can implement this using a bool or an AutoResetEvent:

布尔值:

private volatile bool _isRunning;

public void Run() {
    while (_isRunning)
    {
        doWork();
        Thread.Sleep(1000);
    }
}



的AutoResetEvent:

AutoResetEvent:

private AutoResetEvent _stop;

public void Run() {
    do {
        doWork();
    } while (!_stop.WaitOne(1000));
}



停止()的方法将然后设置 _isRunning 为假,或致电 _stop.Set()

The Stop() method would then set _isRunning to false, or call _stop.Set().

除此之外的AutoResetEvent与解决方案可能会停止快一点,有没有这些方法之间有什么区别?比另一种更好?

Apart from that the solution with AutoResetEvent may stop a little faster, is there any difference between these method? Is one "better" than the other?

推荐答案

C#的挥发性的并不提供所有的担保。它的可能的还是读过期数据。最好使用底层OS同步机制,因为它提供了更强大的担保。

C# volatile does not provide all the guaranties. It may still read stale data. Better to use underlying OS synchronisation mechanism as it provides much stronger guaranties.

这一切都非常深入的discussed ,这里是总之一句话:

All this in great depth discussed by Eric Lippert (really worth reading), here is short quote:

在C#中,善变,不仅意味着确保编译器和
抖动不执行任何代码或重新排序此变量注册缓存
优化
。这也意味着告诉处理器
做到不管它是什么,他们需要做什么来确保我读了
最新值,即使这意味着停止其他处理器,使
他们与他们的高速缓存

In C#, "volatile" means not only "make sure that the compiler and the jitter do not perform any code reordering or register caching optimizations on this variable". It also means "tell the processors to do whatever it is they need to do to ensure that I am reading the latest value, even if that means halting other processors and making them synchronize main memory with their caches".

其实,这最后一点是骗人的同步主内存。挥发的真实语义读取
和写操作相当复杂,比我在这里列出;在
事实的它们实际上并不保证每个处理器停止它所
的操作的
的并从主存储器的更新的高速缓存到/。相反,它们提供
大约存储器之前如何访问较弱的保证和读取之后和
写入可​​以观察到相对于彼此排序。

某些操作,例如为创建一个新线程,进入了一个锁,或
使用的方法互锁家族的一员介绍一下订购的观察更强
担保。如果您想了解更多的细节,
阅读部分3.10和C#4.0规范的10.5.3。

Actually, that last bit is a lie. The true semantics of volatile reads and writes are considerably more complex than I've outlined here; in fact they do not actually guarantee that every processor stops what it is doing and updates caches to/from main memory. Rather, they provide weaker guarantees about how memory accesses before and after reads and writes may be observed to be ordered with respect to each other. Certain operations such as creating a new thread, entering a lock, or using one of the Interlocked family of methods introduce stronger guarantees about observation of ordering. If you want more details, read sections 3.10 and 10.5.3 of the C# 4.0 specification.

坦率地说,我不鼓励你曾经制作volatile字段。挥发性
字段是你正在做的事情简直是疯狂的​​一个标志:你
试图读取和写入两个不同的线程
相同的值没有把锁到位。锁保证存储器读取或
改性内部锁被观察到是一致的,锁保证
只有一个线程在一个时间访问的存储器的给定大块,等等

Frankly, I discourage you from ever making a volatile field. Volatile fields are a sign that you are doing something downright crazy: you're attempting to read and write the same value on two different threads without putting a lock in place. Locks guarantee that memory read or modified inside the lock is observed to be consistent, locks guarantee that only one thread accesses a given hunk of memory at a time, and so on.

这篇关于的AutoResetEvent与布尔来停止一个线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆