![](/img/trans.png)
[英]Does a COM object get released by the CLR when the thread that created it terminates?
[英]Why does the second thread get released before the first one, when they both called WaitOne() and were released by an AutoResetEvent?
假設ThreadA和ThreadB都在同一AutoResetEvent上以此順序調用WaitOne()
。 設置事件后,為什么釋放ThreadB而不是ThreadA?
我進行了一項測試,以了解在設置多個線程正在等待的AutoResetEvent時會發生什么:
private static void Test()
{
// two threads - waiting for the same autoreset event
// start it unset i.e. closed i.e. anything calling WaitOne() will block
AutoResetEvent autoEvent = new AutoResetEvent(false);
Thread thread1 = new Thread(new ThreadStart(WriteSomeMessageToTheConsole));
thread1.Start(); // this will now block until we set the event
Thread thread2 = new Thread(new ThreadStart(WriteSomeOtherMessageToTheConsole));
thread2.Start(); // this will now also block until we set the event
// simulate some other stuff
Console.WriteLine("Doing stuff...");
Thread.Sleep(5000);
Console.WriteLine("Stuff done.");
// set the event - I thought this would mean both waiting threads are allowed to continue
// BUT thread2 runs and thread1 stays blocked indefinitely
// So I guess I was wrong and that Set only releases one thread in WaitOne()?
// And why thread2 first?
autoEvent1.Set();
}
該代碼當然是沒有用的。 這只是一個米老鼠的例子。 這並不重要/緊急。 但是我還是想知道更多...
IIRC,由自動重置事件釋放的線程未指定。 正如其他所有人所提到的,如果要廣播條件,則需要手動重置事件。 如果要釋放一個確切的數字(比如說n的3),則可能要使用信號量。
如果您真的想弄清楚為什么順序可能與您期望的不同,請查看“ Windows Internals”或Mark Russinovich編寫的任何內容。 他很有可能在某處解釋執行資源的等待順序。
從MSDN
MSDN on ManualResetEvent:“在ManualResetEvent上調用WaitOne的線程將阻塞,等待信號。當控制線程完成活動時,它將調用Set來發出信號,表明等待線程可以繼續。 所有等待線程都被釋放。
但是對於AutoResetEvent,MSDN表示:“調用Set會發出信號,使AutoResetEvent釋放等待線程。AutoResetEvent會一直發出信號,直到釋放單個等待線程為止,然后自動返回到未信號狀態。如果沒有線程正在等待,則該狀態會無限期保持發出信號。
”
在AutoResetEvent上 ,Set僅釋放一個線程。 您應該使用ManualResetEvent釋放多個等待線程。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.