我正在维护一个linux服务器应用程序,它是多线程的,用c++编写的。大约有10个模块和数十个std::deque用于消息传递。应用程序使用生产者-消费者模式在模块之间传递网络数据包。
生产者-消费者设计模式在许多情况下都表现良好,但是我认为它不适合我们的应用程序。参见下面的伪代码流聊天:
CSocketModule (for receiving and sending packets)
CSockMod::ReceivePackWorkerThread --> CSockMod::Inque -->
CSockMod::InqueWorkerThread --> CSomeMod::Inque -->
CSomeMod::InqueWorkerThread --> Generates Response Packets -->
CSomeMod::Outque --> CSomeMod::OutqueWorkThread --> //Optional
CSockMod::Outque --> CSockMod::SendPackWorkerThread -->
Linux Kernel::TCP/UDP Layer
For each module, there would be two std::deques for buffering
in/out pakets, two working threads for processing incoming and
outgoing packets respectively.
因为几乎每个Inque和Outque在运行时都将被两个以上的线程访问,因此必须有很多pthread_mutex_locks来同步这些队列。但是,这些锁将使应用程序表现得像一个单线程软件。作为一个服务器应用程序,这可能是不可接受的。
同时,假设CSomeMod::Inque中有1000个数据包,第1000个数据包是来自客户端的控制数据包,那么客户端必须等待CSomeMod::InqueWorkerThread处理完Inque中的999个数据包。控制命令可能会大大延迟!所以,生产者-消费者模式不适合我们的应用程序?还是在这里使用这种模式有误解?我很感激任何帮助,谢谢!
史蒂夫您可以尝试两种简单的方法来直接解决您的关注点:
- 将std::deques和pthread_muexes替换为单生产者,单消费者无锁队列,如下:http://www.1024cores.net/home/lock-free-algorithms/queues/unbounded-spsc-queue或http://www.boost.org/doc/libs/1_53_0/boost/lockfree/spsc_queue.hpp
- 为需要的高优先级项目创建额外的队列。总是先检查这些队列。
你没有提到这些在目前的实践中是否存在问题。在任何情况下:profile, profile, profile