我主要關注的是布爾標誌......可以安全地使用它,而無需任何同步?我已經在幾個地方看過它是原子的(包括文檔)。是否安全使用布爾標誌來阻止線程在C#中運行
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();
}
}
這是以這種方式設計任務的安全方法嗎?任何建議,改進,意見?
注意:我寫了我的自定義CountDownLatch
類,以防您想知道我從哪裏得到它。
更新:
這裏是我的CountDownLatch太:
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();
}
}
@Remus在我的while循環代碼順序中很好的捕獲。關於揮發性標誌:如果在這種情況下標誌是揮發性的,它是否真的有所作爲?如果它錯過了第一次更新,那麼它將在循環中再次執行一次,並在下一次執行時捕獲它。 – Kiril 2010-03-19 04:31:12
如果您不標記爲volatile,生成的代碼可能會將值優化爲註冊表,並且您的線程將永遠不會*看到變化。 – 2010-03-19 04:34:25
@Remus我現在明白了:原子性與線程之間的可見性無關...僅僅因爲一個操作在一個CPU週期內執行,並不意味着結果對其他線程可見,除非值被標記爲易失性。 – Kiril 2010-03-19 04:40:37