2010-12-14 54 views
1

在Windows/C++,如果我有一個結構:安全地共享一個結構在多個線程

struct ListItem { 
    ListItem* next; 
    ListItem* prev; 
    ... 
} 
在兩個主要過程和一些動態加載的DLL運行多個線程

在一起,和所有那些線程需要共享上述結構,我該如何阻止他們彼此跺腳?喜歡的東西:

ListItem* list = ... 

A 

list->next = ... 

B 

我怎麼把A和B處,以防止不超過一個多線程運行在一個list->next = ...時間?

+1

要做的第一件事是封裝整個列表以及所有直接在類中訪問它的列表,並強制任何想訪問它的類來使用該類。這將防止重複代碼,確保使用列表的任何內容都遵守您提出的任何同步方法。 – Blrfl 2010-12-14 18:14:06

回答

5

主要有兩種方式。一種可能是最簡單的方法就是簡單地將每個線程發送給自己的數據結構副本。這樣你就不必使用同步來保護數據,因爲沒有線程共享另一個線程的數據。

但是這在很多情況下都不起作用。有時你確實需要共享一個共同的數據結構。在這種情況下,您需要使用某種形式的同步對象來保護數據結構。 Boost.Threads提供了一些跨平臺的,我相信有人會告訴你如何使用它們。既然你問了關於Windows的具體問題,我會告訴你一個Windows方法。可以使用CRITICAL_SECTION。首先,您需要初始化的關鍵部分在你的主線程,你脫掉你的工作線程之前:

int main() 
{ 
// ... 
    CRITICAL_SECTION cs; 
    InitializeCriticalSection(&cs); 
// ... 
} 

然後將指針傳遞給CS到每個工作線程。 (這留作鍛鍊。)在每個工作線程中,在處理數據之前輸入cs,並在完成時將其保留。

CRITICAL_SECTION* pcs = ...; // passed in from main thread 
EnterCriticalSection(pcs); // this will block until the cs is "available" 
list->next = ... 
LeaveCriticalSection(pcs); // makes the cs available to other threads 

以上是psudocode,有很大的改進空間。例如,關鍵部分應該包裝在RAII對象中,以便在完成後自動銷燬。同樣,鎖定和解鎖也應該在RAII對象中完成,無論您如何退出線程函數,即使面臨異常,也始終解鎖鎖定和解鎖。

您應該注意,CRITICAL_SECTION只能由單個進程使用。如果您需要跨多個進程使用互斥對象類型的對象(而不是您在此需要的),那麼您需要使用named mutex

+0

謝謝!對不起,我不知道它的正確詞彙,但在查看您的CRITICAL_SECTION鏈接後,我看到那是我需要的。 :) – storm 2010-12-14 18:31:22

+0

@風暴:享受和祝你好運 – 2010-12-14 18:33:57

0

使用Windows Mutex對象,您有多個進程可以訪問一個資源。

如果你的線程都在一個進程上,那麼你可以使用EnterCriticalSection/LeaveCriticalSection。

+0

這個'struct'怎麼可能被共享進程間呢? 'CriticalSection'是需要的,或者更好的封裝它的lock_guard類。 – 2010-12-14 18:13:18

+0

我還沒有真正做到這一點,但在Windows中可以創建進程間共享內存。將此內存中的指針轉換爲Stack *。使用指定的互斥鎖保護訪問。你有它。 – ThomasMcLeod 2010-12-14 21:17:14

+0

Windows共享文件和內存:http://msdn.microsoft.com/en-us/library/aa366878(VS.85).aspx – ThomasMcLeod 2010-12-14 21:18:15

0

這功課嗎?無論如何,請嘗試使用Google搜索「關鍵部分」。

+0

我懷疑這是作業。 – 2010-12-14 18:14:34

0
+0

不,在這裏'Mutex'不正確。 – 2010-12-14 18:13:36

+2

@Steve:它*可能*是正確的。它只是不是最佳的。 – 2010-12-14 18:16:53

+0

@約翰,一般的公平點。雖然這個應用程序? – 2010-12-14 18:23:28

0

根據你需要的結構,你可以使用一些無鎖的數據結構,如Win API interlocked SList。這種方式即使在多線程正在執行操作時,數據結構仍然是一致的。