[英]thread safe data exchange between threads/shared memory in C++ on linux
[英]Thread Safe Access to Data Shared Between Objects
我是一個中級程序員,但相對來說還是多線程的新手。 目前,我正在開發一個結構類似於以下的應用程序:
class Client
{
public:
Client();
private:
// These are all initialised/populated in the constrcutor.
std::vector<struct clientInfo> otherClientsInfo;
ClientUI* clientUI;
ClientConnector* clientConnector;
}
class ClientUI
{
public:
ClientUI(std::vector<struct clientInfo>* clientsInfo);
private:
// Callback which gets new client information
// from a server and pushes it into the otherClientsInfo vector.
synchClientInfo();
std::vector<struct clientInfo>* otherClientsInfo;
}
class ClientConnector
{
public:
ClientConnector(std::vector<struct clientInfo>* clientsInfo);
private:
connectToClients();
std::vector<struct clientInfo>* otherClientsInfo;
}
我知道有些人為的例子。 程序流程是這樣的:
構造Client,並填充otherClientsInfo,並使用指向otherClientsInfo的指針構造clientUI和clientConnector。
每當服務器與新的客戶端信息聯系時,clientUI都會調用synchClientInfo(),解析新數據並將其推回otherClientsInfo或刪除一個元素。
調用connectToClients()時,clientConnector將訪問otherClientsInfo中的每個元素,但不會更改它們。
我的第一個問題是我是否假設,如果ClientUI和ClientConnector都同時訪問otherClientsInfo,該程序是否會由於線程不安全而被炸毀?
如果是這種情況,那么我將如何確保對otherClientsInfo線程的訪問安全,例如在某個對象訪問它時以某種方式鎖定它?
我的第一個問題是我是否假設,如果ClientUI和ClientConnector都同時訪問otherClientsInfo,該程序是否會由於線程不安全而被炸毀?
是。 std::vector
大多數實現都不允許並發讀取和修改。 (您會知道您是否使用的是這樣做的 )
如果是這種情況,那么我將如何確保對otherClientsInfo線程的訪問安全,例如在某個對象訪問它時以某種方式鎖定它?
每當訪問向量時,您都至少需要持有一個鎖(簡單的互斥鎖或臨界區或讀/寫鎖)。 由於您只有一個讀寫器,因此沒有讀/寫鎖定。
但是,實際上,正確執行此操作將變得越來越困難,因為您要將te向量暴露給其他類,因此也必須暴露鎖定原語,並記住在每次使用向量時都要獲取它。 最好公開addClientInfo
, removeClientInfo
以及const和非const foreachClientInfo
函數,這些函數將鎖定封裝在Client
類中,而不是讓客戶機擁有的數據的不相交的位在周圍浮動。
和
http://msdn.microsoft.com/zh-CN/library/ms682530%28VS.85%29.aspx
第一個可能對您來說有點高級。 您可以從“關鍵”部分開始(鏈接2)。
我假設您正在使用Windows。
如果ClientUI和ClientConnector同時訪問otherClientsInfo,程序是否會由於線程不安全而被炸毀?
是的,STL容器不是線程安全的。
如果是這種情況,那么我將如何確保對otherClientsInfo線程的訪問安全,例如在某個對象訪問它時以某種方式鎖定它?
在最簡單的情況下,圍繞共享數據訪問的互斥模式...但是,如果您有多個讀者,那么您將尋求更高效的模式。
是否從與synchClientInfo()相同的線程中調用clientConnector(即使全部是回調)? 如果是這樣,您完全不必擔心線程安全。
如果要避免同時訪問相同的數據,可以使用互斥鎖來保護關鍵部分。 例如, Boost :: Thread中的互斥體
為了確保從多個線程對otherClientsInfo
成員的訪問是安全的,您需要使用互斥量對其進行保護。 我在Dr Dobb的網站上寫了一篇文章,介紹如何在C ++中將對象直接與互斥鎖相關聯:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.