【问题标题】:Boost mutex usage for multipart processes提高多部分进程的互斥锁使用率
【发布时间】:2013-09-05 01:49:51
【问题描述】:

我有一个带有套接字通信类的 c++ 程序。每个插座都有一个大的专用 用于组装输出消息的缓冲区,因此用法如下:

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_;  
};

多个线程可能正在尝试发送消息,每个线程由三个或更多调用组成,设置标题、内容,并最终在其途中发送消息。为了避免它们发生冲突,我尝试使用互斥锁一次只保留一个作家。期望的行为是阻止第二个到达的写入器,直到第一个到达的写入器解锁互斥锁。然后被阻止的写入器将能够继续。

这似乎大部分时间都有效,但在极少数情况下(不是每天),死锁似乎仍然会发生。

我更熟悉使用范围锁的更简单的锁问题,但这些概念可能无法完美地转化为这个问题,在这个问题上,锁需要在对拥有锁的对象的多次调用中保持不变。

通过阅读 Boost 同步教程,我认为有更好的方法可以做到这一点,但不清楚哪种方法最好。

任何建议将不胜感激。

【问题讨论】:

    标签: c++ multithreading sockets boost


    【解决方案1】:

    由于每个线程都有自己的缓冲区,因此每个线程都在自己的缓冲区中构建完成消息,然后锁定互斥体并发送消息。

    更好的是,有一个线程来实际发送消息,还有 N 个线程来创建它们。在两者之间放置一个线程安全队列,因此线程创建一条消息,将其放入队列中,然后(如果需要)返回创建另一条消息。消息发送者只是不断地等待队列中的消息,检索它,发送它,然后重复。

    您可能还需要一个线程安全的缓冲区集合,因此当消息发送后,发送线程可以将缓冲区放置在消息构建器线程可以在需要时再次使用它的位置。

    顺便说一句:对于缓冲区,我会使用std::stringstd::vector,而不是原始数组。

    【讨论】:

    • 感谢您的回复。我最终创建了一个私有缓冲区消息类,然后使用作用域锁将缓冲区复制到公共套接字缓冲区并释放锁。套接字将按自己的时间表发送。顺便说一句,std::string 与二进制数据不兼容(我正在发送 blob),并且两者都使用堆分配,这比没有分配开销的私有基于堆栈的缓冲区慢得多。
    • @user2748924:std::string 可以处理二进制数据(尽管这是我在建议 std::vector 时想到的那种东西)。速度是我建议使用缓冲区集合的原因,因此您可以预先分配缓冲区,然后重新使用它们,因此您只需分配一次。
    猜你喜欢
    • 1970-01-01
    • 2011-07-16
    • 1970-01-01
    • 1970-01-01
    • 2011-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-09
    相关资源
    最近更新 更多