2009-10-06 3 views
0

Я что-то вроде промежуточного программиста, но относительно новичок в многопоточности. На данный момент я работаю над приложением, со структурой, аналогичной следующей:Thread Безопасный доступ к данным, разделяемым между объектами

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 и строит clientUI и clientConnector с указателем на otherClientsInfo.

  • clientUI вызывает synchClientInfo() в любое время, когда сервер связывается с ним с новой информацией о клиенте, анализирует новые данные и возвращает их обратно в otherClientsInfo или удаляет элемент.

  • clientConnector будет обращаться к каждому элементу в otherClientsInfo при вызове connectToClients(), но не будет изменять их.

Мой первый вопрос, является ли мое предположение, что если оба ClientUI и ClientConnector доступ otherClientsInfo в то же время, будет программа бомба из-за потоков небезопасность?

Если это так, то как я могу сделать доступ к потоку в другой среде, как, возможно, каким-то образом заблокировать его, пока один объект обратится к нему?

+0

библиотека Что нить вы используете? – hirschhornsalz

+0

Я использую инструментарий QT, который вызывает pthreads, поскольку я нахожусь в Linux/BSD , насколько я знаю. Из других ответов я думаю, что это может быть хорошая идея создать класс вокруг вектора и, возможно, использовать мьютексы до контролировать доступ к нему. Хорошая/плохая идея? – Conor

+0

Хорошая идея, что-то вроде предложения Пита Киркхэма, вероятно, будет для вас лучшим. –

ответ

0

См Reader/Writer Locks in C++

и

http://msdn.microsoft.com/en-us/library/ms682530%28VS.85%29.aspx

Первый, вероятно, немного продвинулся для вас. Вы можете начать с раздела Critical (ссылка 2).

Я предполагаю, что вы используете Windows.

+0

Я на самом деле разрабатываю для Linux и BSD. Спасибо за рекомендации, я проверю их сейчас. – Conor

0

Если и ClientUI, и ClientConnector одновременно получают доступ к otherClientsInfo, выйдет ли программа из-за отсутствия потоков?
Да, контейнеры STL не являются потокобезопасными.

Если это так, то как я могу сделать доступ к потоку threadIndIllInfo безопасным, как возможно, каким-то образом заблокировать его, пока один объект обратится к нему?
В самом простом случае шаблон взаимного исключения вокруг доступа к общим данным ... если бы у вас было несколько читателей, вы бы пошли на более эффективный шаблон.

+0

Я понимаю, что мьютексы предотвращают доступ нитей к данным в той же функции, это правильно? Возможно, я неправильно понял ваш ответ, но то, что происходит в программе, состоит в том, что вектор otherClientsInfo может одновременно получать доступ к двум различным объектам разных типов, будут ли мьютекс препятствовать доступу одного объекта к нему, пока другой объект обратится к нему? Также вы можете указать мне в направлении хорошей ссылки на читателей и связанные с ними шаблоны? Благодарим вас за ответ. – Conor

+0

Мьютексы - это инструмент, который поможет вам избежать одновременного доступа к критическим данным, см., Например, http://en.wikipedia.org/wiki/Mutual_exclusion –

+0

И да, проблема в одновременном доступе ... и именно там блокировки, такие как мьютексы помочь тебе. –

0

Является ли clientConnector вызываемым из того же потока, что и synchClientInfo() (даже если это все обратный вызов)? Если это так, вам не нужно беспокоиться о безопасности потоков.

Если вы хотите избежать одновременного доступа к тем же данным, вы можете использовать мьютексы для защиты критического раздела.Для exmample, mutexes from Boost::Thread

1

Мой первый вопрос, является ли мое предположение, что если оба ClientUI и ClientConnector доступ otherClientsInfo в то же время, будет программа бомба из-за потоков небезопасность?

Да. Большинство реализаций std::vector не допускают одновременного чтения и изменения. (Вы знаете, если бы вы использовали one which did)

Если это так, то как бы я идти о том, чтобы доступ к otherClientsInfo поточно, как, возможно, каким-то образом запирая его в то время как один объект обращается к нему?

Для доступа к вектору требуется как минимум блокировка (либо простой мьютекс, либо критический раздел, либо блокировка чтения/записи). Поскольку у вас есть только один читатель и писатель, нет смысла иметь блокировку чтения/записи.

Тем не менее, на самом деле выполнение этого вопроса будет становиться все более трудным, поскольку вы подвергаете te vector другим классам, поэтому также придется выставлять запирающий примитив и не забывать его приобретать всякий раз, когда вы используете вектор. Возможно, лучше разоблачить addClientInfo, removeClientInfo и const и non-const foreachClientInfo функции, которые инкапсулируют блокировку в классе Client, вместо того, чтобы иметь непересекающиеся биты данных, принадлежащих клиенту, плавающим вокруг места.

+0

Я использую инструментарий QT, который имеет класс QVector, функции которого являются реентерабельными. Я не уверен, что резидентство решит мою проблему в в этом случае, но выйдет из QVector или обертывает std :: vector в классе и предоставляет функции, которые вы предложили с мьютексами, предоставили мне решение? – Conor

+0

Помещение мьютексов вокруг всех обращений к вектору обеспечит решение. Это проще сделать, если вы не выставляете вектор так, чтобы все обращения выполнялись с одним классом, а следовательно, и с функциями манипулирования им. Я не знаю QT, поэтому не могу прокомментировать, будет ли это безопасно. –

+0

А затем просто передайте указатель на класс-оболочку конструктору как ClientConnector, так и ClientUI? Я мог бы принять эту идею и использовать с QVector, вероятно, имеет смысл использовать типы QT, когда кодирование с QT ... Большое спасибо за вашу помощь. – Conor

0

Для обеспечения безопасности доступа к члену otherClientsInfo из нескольких потоков вам необходимо защитить его мьютексом. Я написал статью о том, как непосредственно связать объект с помощью мьютекса в C++ над на сайте доктора Добба:

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

Смежные вопросы