簡體   English   中英

線程安全訪問對象之間共享的數據

[英]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向量暴露給其他類,因此也必須暴露鎖定原語,並記住在每次使用向量時都要獲取它。 最好公開addClientInforemoveClientInfo以及const和非const foreachClientInfo函數,這些函數將鎖定封裝在Client類中,而不是讓客戶機擁有的數據的不相交的位在周圍浮動。

請參閱C ++中的讀取器/寫入器鎖

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 ++中將對象直接與互斥鎖相關聯:

http://www.drdobbs.com/cpp/225200269

暫無
暫無

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

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