2013-06-01 123 views
1

所以我有多個線程訪問此函數來檢索數據庫信息,它是線程安全的嗎?C++向量是線程安全的嗎?多線程

vector<vector<string> > Database::query(const char* query) 
{ 
    pthread_rwlock_wrlock(&mylock); //Write-lock 
    ... 
    vector<vector<string> > results; 
    results.push... 
    pthread_rwlock_unlock(&mylock); //Write-lock 

    return results; 
} 

對於編輯 - >有時'修復'>>到>>不是一個好主意,但感謝其餘的。

+0

很難確定你在問什麼。使用像這樣的本地向量是線程安全的,因爲它是在堆棧上創建的。但是我們不能告訴你,如果你的函數是線程安全的。 我可以告訴你,這將是低效的,因爲在構建你的向量的字符串向量之後,你會返回它的一個副本而不是原始的。 – kfsone

回答

1

一般來說,多個線程可以容納「讀」鎖。只有一個線程可以保持「寫入」鎖定。當有「寫入」鎖定時,可能不會持有「讀取」鎖定。

這意味着,雖然mylock被鎖定在query方法內,但沒有其他人可以將其鎖定爲讀取或寫入,因此它是線程安全的。你可以閱讀更多關於讀者 - 作家鎖定here。無論你是否需要鎖定在那裏的互斥鎖是另一個問題。然而,代碼不是exception-safe。您必須僱用RAII才能自動解鎖互斥鎖,包括堆棧解除鎖定。

+0

關於異常安全的任何教程?或者只是一個簡單的try {} catch()會做什麼? –

+0

@БайИван:看看[這個問題](http://stackoverflow.com/questions/2635882/raii-tutorial-for-c)。 Try-catch也可以,但通常更容易出錯並且難寫。 – 2013-06-01 23:12:04

2

由於results是一個局部變量,因爲每個線程都會有唯一的副本(它位於堆棧上,以某種方式動態分配的向量的內容等),所以它本身是安全的, 。所以只要你的數據庫是線程安全的,你根本不需要任何鎖。如果數據庫不是線程安全的,當然你需要保護它。

正如在其他答案中指出的那樣,如果由於某種原因,例如創建一個字符串導致throw bad_alloc;,您需要處理該問題的後果,並確保該鎖已解鎖(除非您真的希望以使所有其他線程死鎖!)

+0

這是我需要聽到的;數據庫不是線程安全的,因此我鎖定它:) –

0

它是線程安全的,因爲results被創建爲局部變量,因此只有一個線程會訪問此方法中的任何結果實例。

如果您因爲某些其他原因需要線程安全的向量,請在Threadsafe Vector Class for C++上查看此答案。