2013-03-28 34 views
0

對不起標題的第4必須跑,我找不到更好的解釋我的問題...線程同步問題,3個線程同時運行,而其他人都在等待

我有一個艱難的時間,試圖在我的應用程序中同步不同的線程。對於在這個問題上有新面貌的人來說,這可能是一個簡單的問題,但經過幾個小時的關於僵局的調查之後,我的頭部正在爆炸,而且我找不到一個安全可靠的寫同步機制的方法:(

基本上,我有一個在多線程運行的.NET程序(在一個單一的過程中的一切,所以無需IPC)我有4個線程。

  • 1線,說它被稱爲SpecificThread。有一個System.Timers.Timer定期執行一些代碼
  • 3個其他線程,每個線程運行一個服務,執行一些c (while (true) loop + Thread.Sleep(few ms))。

所有3項服務必須同時運行。我保證他們的併發執行是線程安全的。 第四個線程,SpecificThread,必須定期執行其代碼,但是它必須阻止執行其他3個服務

所以基本上我有SpecificThread定期執行代碼。當SpecificThread想要定期執行其代碼時,它必須等待其他服務完成其任務。當所有其他3個服務完成其任務時,它必須執行其特定代碼而其他3個服務被阻止。當其執行SpecificCode時,其他3個服務可以再次運行其代碼。

我有一個在所有4個線程之間共享的SynchronizationContext對象的共享實例。我可以用它來同步我的主題:

public class SynchronizationContext 
{ 
    public void StartService1() 
    { 
     ... 
    } 
    public void StopService1() 
    { 
     ... 
    } 
    ... 

    public void StartSpecificCode() 
    { 
     // Some sync here that wait until all 3 services completed their 
     // respective tasks 
    } 
    public void NotifySpecificCodeCompleted() 
    { 
     // Some sync here that allows services 1 to 3 to execute again 
    } 
} 

3個服務執行機制是這樣的:

// Only exits the loop when stopping the whole .Net process 
while (myService.IsRunning) 
{ 
    try 
    { 
     this.synchronizationContext.StartService1(); 

     // Do some job 
    } 
    finally 
    { 
     this.synchronizationContext.EndService1(); 

     // Avoids too much CPU usage for nothing in the loop 
     Thread.Sleep(50); 
    } 
} 

SpecificThread執行機制:

// System.Timers.Timer that is instantiated on process start 
if (this.timer != null) 
{ 
    this.timer.Stop(); 
} 

try 
{ 
    // Must blocks until computation is possible 
    this.synchronizationContext.StartSpecificCode(); 

    // Some job here that must execute while other 3 
    // services are waiting 
} 
finally 
{ 
    // Notify computation is done 
    this.synchronizationContext.NotifySpecificCodeCompleted(); 

    // Starts timer again 
    if (this.timer != null) 
    { 
     this.timer.Start(); 
    } 
} 

我想不通了解如何使用關鍵部分,因爲只有SpecificThread必須在其他人在等待時運行。我沒有找到與SemaphoreAutoResetEvent(他們的用法在我的代碼中引入了一個難以調試的死鎖)的方法。我在這裏用盡想法...也許Interlocked靜態方法會有幫助嗎?

最後一句話:我的代碼必須與.net 3.5跑,我不能使用任何TPL也不CountdownEvent類...

任何幫助表示讚賞!

+0

也許會有所幫助http://stackoverflow.com/questions/15657637/condition-variables-c-net – Lanorkin 2013-03-28 13:13:07

回答

1

ReaderWriterLockSlim聽起來像是最能幫助你的工具。讓每個服務的拿出自己的循環體裏面讀鎖:

while (true) 
{ 
    try 
    { 
     lockObject.EnterReadLock(); 

     //Do stuff 
    } 
    finally 
    { 
     lockObject.ExitReadLock(); 
    } 
} 

那麼你的第四線可以當它要做到這一點的工作進入一個鎖。讀寫器鎖的工作方式是,只要沒有寫者持有鎖,任何數量的讀者都可以持有鎖,並且一次只能有一個寫者持有該鎖。這意味着三名工人都不會阻止其他工人,但是如果第四條線程正在運行,工人就會打嗝,這就是你想要的正好是

+0

哇,這聽起來正是我期待的!我現在正在測試它 – ken2k 2013-03-28 13:27:20

+0

嗯,這完全**的工作**。我的'SynchronizationContext'類現在只依賴於'ReaderWriterLockSlim'類,它非常簡單且易於維護。非常感謝,我只是想建立自己的'ReaderWriterLockSlim'類,你節省了我幾個小時。太糟糕了,我無法多次提醒你的答案! – ken2k 2013-03-28 13:56:14