Omn*_*ous 16 c++ python linux multithreading event-driven
我想生成线程来执行某些任务,并使用线程安全队列与它们进行通信.在我等待的时候,我也想对各种文件描述符做IO.
推荐的方法是什么?我是否必须创建一个线程间管道并在队列从无元素转到某些元素时写入它?有没有更好的方法?
如果我必须创建线程间管道,为什么实现共享队列的更多库不允许您将共享队列和线程间管道创建为单个实体?
我想这样做的事实是否意味着一个基本的设计缺陷?
我问这个关于C++和Python的问题.我对跨平台解决方案略感兴趣,但主要对Linux感兴趣.
更具体的例子......
我有一些代码将搜索文件系统树中的东西.我有几个通过套接字向外界开放的通信渠道.可能(或可能不)导致需要搜索文件系统树中的内容的请求将到达.
我将隔离在一个或多个线程中搜索文件系统树中的东西的代码.我想接受这样的请求,这些请求导致需要搜索树并将它们放入由搜索器线程完成的线程安全队列中.结果将被放入已完成搜索的队列中.
我希望能够在搜索过程中快速为所有非搜索请求提供服务.我希望能够及时对搜索结果采取行动.
处理传入的请求通常意味着使用某种事件驱动的体系结构epoll.磁盘搜索请求队列和结果返回队列意味着一个线程安全队列,它使用互斥锁或信号量来实现线程安全.
等待空队列的标准方法是使用条件变量.但是,如果我需要在等待期间提供其他请求,那将无效.我最终一直在轮询结果队列(并且平均将结果延迟轮询间隔的一半),阻塞而不是服务请求.
每当使用事件驱动的体系结构时,需要一个机制来报告事件完成.在Linux上,如果使用文件,则需要使用select或poll族中的某些内容,这意味着使用管道来启动所有无文件相关事件.
编辑:Linux有eventfd和timerfd.这些可以添加到您的epoll列表中,并用于epoll_wait分别从另一个线程或计时器事件触发时.
还有另一种选择,那就是信号.可以使用fcntl修改文件描述符,以便在文件描述符变为活动时发出信号.然后,信号处理程序可以将文件就绪消息推送到您选择的任何类型的队列上.这可能是一个简单的信号量或互斥/ condvar驱动的队列.由于现在不再使用select/ poll,因此不再需要使用管道来排队基于文件的消息.
健康警告:我没有尝试过,虽然我不明白为什么它不起作用,但我真的不知道这种signal方法的性能影响.
我已经使用您提到的 pipe() 和 libevent(包装 epoll)解决了这个确切的问题。当其输出队列从空变为非空时,工作线程将一个字节写入其管道 FD。这会唤醒主 IO 线程,然后主 IO 线程可以获取工作线程的输出。这很好用,实际上编码起来非常简单。