我目前正在接受多個客戶端的服務器上工作。什麼時候用C++類鎖定互斥鎖
在服務器端我有一個線程池(手工製作,做工精細)午飯多線程:
ThreadPool::bind(new TCPReceiver());
ThreadPool::bind(new TCPSender());
一旦一個類被綁定到ThreadPool
,其start()
函數被調用。
所以basicaly什麼我的服務器做的是:
- 線程綁定
- 接受一個或多個客戶
- 客戶的指針到TCPReceiver客戶端列表
- TCPReceiver執行
socket.receive()
,並推動接收數據,以在客戶端的消息隊列
- TCPReceiver執行
- 附加客戶端的指針TCPSender客戶名單
- TCPSender執行
socket.send()
和發送端的輸出消息隊列
- TCPSender執行
因此,一旦一個客戶端連接,其類的指針被連接到2個線程,一個誰讀的插座,一個發送套接字。儘管如此,主線程(服務器)彈出客戶端的輸入消息隊列。
class Server {
std::list<Client*> clients;
TCPReceiver receive;
TCPSender send;
public:
void *start();
}
class Client {
std::list<NetworkMessage*> inQueue;
IMutex *inMutex;
std::list<NetworkMessage*> outQueue;
IMutex *outMutex;
Socket *socket;
}
class TCPReceiver {
std::list<Client*> clients;
public:
void *start();
}
class TCPSender {
std::list<Client*> clients;
public:
void *start();
}
我的問題(s)爲:
從服務器/ TCPReceiver/TCPSender類,我可以訪問/使用客戶端指針沒有鎖定的客戶端類,但只能鎖定客戶端的消息隊列彈出/推在上面 ?
請問2個線程可以同時調用不同的客戶的會員功能?
我可以調用的std ::列表的成員不鎖定的std ::列表(見(*吧) - > inQueue.empty()調用)的功能呢?
void Server::start() {
for (std::list<Client*>::iterator it = this->clients.begin(); it != this->clients.end(); ++it) {
if (!(*it)->inQueue.empty()) {
(*it)->inMutex->lock();
(*it)->inQueue.front();
(*it)->inQueue.pop_front();
(*it)->inMutex->unlock();
}
}
}
同時對TCPReceiver:
void TCPReceiver::start() {
for (std::list<Client*>::iterator it = this->clients.begin(); it != this->clients.end(); ++it) {
std::string msg = (*it)->socket->receive();
if (!msg.empty()){
(*it)->inMutex->lock();
(*it)->inQueue.push_back(msg);
(*it)->inMutex->unlock();
}
}
}
(我知道插座應該有一個互斥量太多,但它不是我想要現在就understund)
正如一個側面說明:您可能需要手動考慮基於RAII基於作用域的鎖,而不是鎖定和解鎖互斥 - 這樣你可以避免引起的異常(見的情況下不釋放互斥死鎖: lock_guard](http://en.cppreference.com/w/cpp/thread/lock_guard))。 – Hulk
你說得對。今天早上我在尋找答案時瞭解到了這一點。我會盡快實施它,thx的提示。 – EoiFirst
每個客戶端都有自己的消息列表,因此每個客戶端都有相應的互斥鎖。 – EoiFirst