是安全的使用布尔标志从在C#停止运行一个线程 [英] Is it safe to use a boolean flag to stop a thread from running in C#
问题描述
我主要关注的是布尔标志......是安全的使用它没有任何同步?我在几个地方看,它的原子(包括文档)。
类MyTask
{
私人的ManualResetEvent startSignal;
私人CountDownLatch闩锁;
私人布尔运行; MyTask(CountDownLatch闩锁)
{
运行= FALSE;
this.latch =锁存器;
startSignal =新的ManualResetEvent(假);
} //它运行在一个线程的方法
公共无效的run()
{
startSignal.WaitOne();
而(运行)
{
startSignal.WaitOne();
// ...一些code
}
latch.Signal();
} 公共无效停止()
{
运行= FALSE;
startSignal.Set();
} 公共无效启动()
{
运行= TRUE;
startSignal.Set();
} 公共无效暂停()
{
startSignal.Reset();
} 公共无效简历()
{
startSignal.Set();
}
}
这是一种安全的方式来设计这样一个任务?任何建议,改进意见?
注:我写了我的自定义 CountDownLatch
类的情况下,你想知道我是从得到它
更新:结果
这里是我的CountDownLatch太:
公共类CountDownLatch
{
私人挥发性INT m_remain;
私人的EventWaitHandle m_event; 公共CountDownLatch(诠释计数)
{
如果(计数℃,)
抛出新ArgumentOutOfRangeException();
m_remain =计数;
m_event =新的ManualResetEvent(假);
如果(m_remain == 0)
{
m_event.Set();
}
} 公共无效信号()
{
//最后一个线程还对信号设置事件。
如果(Interlocked.Decrement(REF m_remain)== 0)
m_event.Set();
} 公共无效等待()
{
m_event.WaitOne();
}
}
您更好地标记它的 挥发性
虽然:
volatile关键字指示
字段可能由多个被修改
并发执行多个线程。字段
被声明为挥发不
受编译器的优化
假定由单个线程访问。这个
确保了最先进的最新值
在野外present在任何时候。
块引用>不过,我会改变你的循环:
startSignal.WaitOne();
而(运行)
{
// ...一些code
startSignal.WaitOne();
}由于它是在您的文章中一些code'当线程可能会执行的停止的(即当停止叫),这是意想不到的,甚至可能不正确。
My main concern is with the boolean flag... is it safe to use it without any synchronization? I've read in several places that it's atomic (including the documentation).
class MyTask { private ManualResetEvent startSignal; private CountDownLatch latch; private bool running; MyTask(CountDownLatch latch) { running = false; this.latch = latch; startSignal = new ManualResetEvent(false); } // A method which runs in a thread public void Run() { startSignal.WaitOne(); while(running) { startSignal.WaitOne(); //... some code } latch.Signal(); } public void Stop() { running = false; startSignal.Set(); } public void Start() { running = true; startSignal.Set(); } public void Pause() { startSignal.Reset(); } public void Resume() { startSignal.Set(); } }
Is this a safe way to design a task in this way? Any suggestions, improvements, comments?
Note: I wrote my custom
CountDownLatch
class in case you're wondering where I'm getting it from.Update:
Here is my CountDownLatch too:public class CountDownLatch { private volatile int m_remain; private EventWaitHandle m_event; public CountDownLatch (int count) { if (count < 0) throw new ArgumentOutOfRangeException(); m_remain = count; m_event = new ManualResetEvent(false); if (m_remain == 0) { m_event.Set(); } } public void Signal() { // The last thread to signal also sets the event. if (Interlocked.Decrement(ref m_remain) == 0) m_event.Set(); } public void Wait() { m_event.WaitOne(); } }
解决方案You better mark it
volatile
though:The volatile keyword indicates that a field might be modified by multiple concurrently executing threads. Fields that are declared volatile are not subject to compiler optimizations that assume access by a single thread. This ensures that the most up-to-date value is present in the field at all times.
But I would change your loop:
startSignal.WaitOne(); while(running) { //... some code startSignal.WaitOne(); }
As it is in your post the 'some code' might execute when the thread is stopped (ie. when Stop is called) which is unexpected and may be even incorrect.
这篇关于是安全的使用布尔标志从在C#停止运行一个线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!