2011-03-18 87 views
0

考慮到以下要求,有人可以發佈一個非常簡單的代碼示例,說明如何使用多線程,並同時正確使用鎖來保持共享數據「安全」?簡單線程示例需要

假設你聲明一個整數x爲100.然後,你想產生10個線程來執行一些操作。隨着每個線程完成該動作,它會遞減x。我知道你可以使用互鎖,但是當你評估這種情況時你是否也需要鎖定?換句話說,在執行操作之前,您需要確保x大於0。

回答

4

你可以用每次訪問xlock關鍵字:

private object xLock = new object(); 

... 

lock (xLock) 
{ 
    // Any read or write access to x 
} 

這將確保是原子的所有訪問在X,並沒有對線程安全相關的危險。

0

如果你想要做的事情只是版本實現自己的邏輯

lock(somecommonreference) 
{ 
    if (x>0) x--; 
} 
4

如果要編寫簡單的多線程程序,考慮在C#4.0使用並行擴展。

簡單的多線程程序與鎖和可變的共享數據是從來沒有簡單。

2

你可能不想減少計數器操作完成後,作爲計數器可以是1,所有10個線程會檢查它,發現它是大於零,並開始執行行動,只有所有在完成時遞減。

您可以使用Interlocked.Decrement遞減計數器和執行操作前檢查它的價值不鎖定:

int temp = Interlocked.Decrement(x); 

if(temp >= 0) //temp is the decremented value 
{ 
    //perform action 
} 
+0

是的,但如果操作失敗會怎麼樣。我不想減少。 – JedMoney 2011-03-18 21:54:28

+0

行動失敗的可能性使它更復雜一點。您可能希望查看C#4.0中的並行擴展,作爲jdv在他的回答中提出的建議,並在嘗試設計自己的設計之前查看是否適合您的要求。多線程程序很容易很快變得非常複雜。 – 2011-03-18 22:39:37

2

你想用Interlocked.CompareExchange。假設您要修改名爲Counter的共享變量。

int count = Counter; 
if (count == 0) 
    return; 
if (Interlocked.CompareExchange(ref Counter, count-1, count) == count) 
{ 
    // Counter was decremented. 
    // perform your processing. 
} 

如果您希望線程在退出前最多處理10個項目,可以將其包裝在一個循環中。

請注意,計數器控制條目的處理方法。也就是說,在邏輯上它的工作原理是這樣的:

if (counter > 0) 
{ 
    --counter; 
    DoAction(); 
} 

你的問題似乎問這樣的事情:

if (counter > 0) 
{ 
    DoAction(); 
    --counter; 
} 

但是,如果你這樣的代碼,那麼你很可能會調用超過100 DoAction更多次數(或者counter的初始值),因爲其他線程可以在最後一個線程完成之前開始動作。