我有一个带有套接字通信类的 C++ 程序。每个 socket 都有一个大的专用 用于组装输出消息的缓冲区,因此用法如下:
class CSocketClass {
public:
SetMsgHeader(int n) { Mutex_.lock(); DoWhateverIsNeededToSetHeaderInBuffer(n); } // where n would be the message type
SetMsgField(double a); { DoWhateverIsNeededToSetDataInBuffer(a); } // where a would be some arbitrary content
SendMsg(); { DoWhateverIsNeededToSendBuffer(); Mutex_.unlock(); } // where this would send the number of bytes added to the buffer since the header was set
private:
char buffer[reallylarge];
MiscSocketApparatus...
boost::mutex Mutex_;
};
多个线程可能会尝试发送消息,每个线程由三个或更多调用组成,设置标题、内容,并最终在途中发送消息。为了避免它们发生冲突,我试图通过使用 Mutex 一次只保留一个编写器。理想的行为是阻止第二个到达的写入器,直到第一个到达的写入器解锁互斥体。然后被阻止的作者将能够继续。
这似乎在大多数时候都有效,但在极少数情况下(不是每天),似乎仍然会发生死锁。
我更熟悉使用作用域锁的更简单的锁问题,但这些概念可能无法完美地转化为这个问题,在这个问题中,锁需要在对拥有锁的对象的多次调用中保持不变。
通过阅读 Boost 同步教程,我认为有更好的方法可以做到这一点,但不清楚什么是最好的。
如有任何建议,我们将不胜感激。
最佳答案
由于每个线程都有自己的缓冲区,因此每个线程都在自己的缓冲区中构建完整消息,然后锁定互斥锁并发送消息。
更好的是,有一个线程来实际发送消息,并有 N 个线程来创建它们。在两者之间放置一个线程安全的队列,以便线程创建一条消息,将其放入队列,然后(如果需要)返回创建另一条消息。消息发送者只是不断地等待队列中的消息,检索它,发送它,然后重复。
您可能还需要一个线程安全的缓冲区集合,以便在发送消息后,发送线程可以将缓冲区放在消息生成器线程可以在需要时再次使用它的地方。
顺便说一句:对于缓冲区,我将使用 std::string
或 std::vector
,而不是原始数组。
关于c++ - boost 多部分进程的互斥量使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18626501/