簡體   English   中英

使用線程對矢量進行排序

[英]Sorting a vector using threads

C ++ STL中定義的向量是重入的還是線程安全的? 我可以使用兩個線程並在不使用互斥鎖的情況下在矢量的兩半上工作(在這種情況下是排序)嗎? 例如:

int size = (Data_List.size())/2;

Thread A()
{

................ // Do we need to lock Data_list with a mutex
 sort(Data_List.begin(),Data_List.begin()+size,cmp);
}

Thread B()
{
....// Do we need to lock Data_list with a mutex
sort(Data_List.begin()+(size+1),Data_List.end(),cmp);
}

我的問題是我們需要使用互斥鎖來鎖定Data_List的訪問權限嗎?

注意:cmp函數是一個常規的int比較函數。

只要線程在不同的內存區域工作,並且比較函數只適用於那個內存和局部變量,你應該沒問題。 本質上,您通過划分線程之間的工作來“鎖定”表的每一半,並且只讓線程處理其一半的數據。

幾乎,但不完全。 這個代碼通常不是線程安全的,即使假設實現對向量的線程安全性做出了合理的保證。

假設Data_List::value_type是您的體系結構不提供原子訪問的類型。 例如,在x86上,字節寫入和對齊的字和雙字寫入是原子的,但是短寫不是,並且用戶定義類型的寫入不是,除非它們碰巧是一個好的大小和對齊。 如果您的UDT大小為3,則可能會出現問題。

要執行非原子短寫,實現可能會執行兩個字節寫操作。 或者它可能加載單詞,修改兩個字節,然后將單詞寫回。 在字節寫入昂貴的架構上,后者非常合理。

現在,假設您的實現執行后者。 進一步假設你的向量分割恰好將一個單詞的前半部分留在一個部分中,而另一個部分留在另一個部分中。 最后假設兩個不同的線程都試圖同時修改該單詞。 這可能會出錯 - 它們可能都讀取相同的值,同時修改它,但是一次回寫將在另一次之前發生,因此其中一個修改將被覆蓋並丟失。

默認情況下,原子字節訪問不是通用的,我懷疑默認情況下任何實現都會進行原子位訪問。 因此,即使其他向量類型是安全的, vector<bool>也是一個可能的問題:向量的除法可能會在一個字節的中間。 並不是說您通常會以這種方式 bool進行排序 ,但是還有其他操作可能會嘗試划分向量,或者您的代碼可能是通用的。

您通常可以期望word-access是原子的(在C或C ++中, int訪問)。 但是語言標准不能保證,因此sig_atomic_t 你說你的cmp是一個int比較函數,它表明你的向量可能包含整數。 但你可以使用int比較函數很好地比較短褲,所以我不知道。

您實際需要做的是非常仔細地檢查您的實現/平台,並查看從多個線程安全訪問內存的內容。 對於int的向量,它可能很好。

您可以將GCC的並行模式(如果使用GCC)用於各種算法的線程版本。 http://gcc.gnu.org/onlinedocs/libstdc++/manual/parallel_mode.html

從技術上講,標准說這些類不是線程安全的,所以如果你從[]運算符之類的東西設置數據,那么從技術上來說就是在一個對象上進行多次寫入。 另一方面,在交流陣列的不同部分上操作是安全的...所以這里似乎存在沖突。 如果你想要干凈利落,請取第一個元素的地址並將其視為一個c-array。 這里有很多答案說只要你在陣列的不同部分就可以了,雖然在許多實現中這可能都是正確的

- >我認為重要的是要注意一個實現是免費的,不能使它安全。

如果線程處理向量的不相交部分,則不應該有任何問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM