C++中的多线程事件处理



当我们想要设计一个通用的事件处理(I/O多路分解)或反应器模式模型时。我们使用的底层系统调用是"select"或"poll"。但这两个系统调用在FD的公共集合上都不是线程安全的。不能在多线程环境中使用。

使用跨多个I/O的多个线程处理事件的更好方法是什么。

我可以看到的一种方式是,主线程记录任何事件并推送到线程池的共享队列中。但是工作线程不能通过I/O发送数据会导致同步问题。还有内存溢出的缺点。

欢迎所有可能的建议。提前感谢。

大多数Unixes提供了可在多线程环境中使用的更具扩展性的选择/轮询替代方案:

  • Linux有epoll
  • BSD具有kqueue
  • Solaris具有事件完成端口

但是,在多线程环境中正确处理可能很棘手,所以您可能需要查看现有的抽象层,如boost.asio

另一方面,boost.asio确实引入了一些不可忽略的开销——我已经收集了一些关于这方面的信息,并在http://nginetd.cmeerw.org

看看"生产者-消费者问题",这是线程安全问题的一个很好的起点。它还可以扩展到多个生产商和多个消费者。

一种方法是拥有一个输入线程、一个输出线程、几个工作线程和两个阻塞队列。

输入线程解析输入消息,并将它们放在队列1中。工作线程都在队列1上等待,处理消息并将它们的任何输出放入队列2中。输出线程在队列2上等待并串行化它的输出

InputThread:
    Loop:
        M = ReadNextMessage
        Q1.push(M)
AddOutput(O):
    Q2.push(O)
WorkerThread:
    Loop:
        M = Q1.pop
        ProcessMessage(M) using AddOutput as needed
OutputThread:
    Loop:
        O = Q2.pop
        WriteOutput(O)

然而,我不知道你说select不安全是什么意思?所有系统调用在技术上都是线程安全的

一个叫凯格尔的人写了一篇题为"CY10K问题"的文章,这篇文章很古老,但仍然很有趣。。

http://www.kegel.com/c10k.html

它讨论了在Linux上构建"multi-io"程序的不同方法,以及每种方法的优缺点。

最新更新