非阻塞定时器和服务器的解决方案是提升线程

Solution for non-blocking timer and server is boost threads?

本文关键字:解决方案 线程 服务器 定时器      更新时间:2023-10-16

我的项目有一个队列、一个服务器和一个计时器。服务器接收数据并将其放入队列,计时器处理队列。当队列被处理时,外部进程将使用popen打开,这意味着popen将阻塞计时器,直到进程结束。

如果我错了,请纠正我的错误,但由于服务器和计时器都链接到同一个io_service,如果服务器接收到数据,它将以某种方式阻止io_seervice继续到下一个事件,反之亦然,如果队列中的进程正在执行,则计时器会阻止。

我正在考虑一个基于boost::thread的解决方案,但我不确定应该使用什么架构,因为我从未使用过线程。我的选择是:

两个线程-一个用于定时器,一个用于服务器,每个线程使用自己的io_service一个线程-一个用于具有自己io_service的计时器。服务器仍处于主进程中

在这两种方式中,队列(一个简单的映射)都必须共享,所以我想我在互斥和其他方面会遇到一些问题

如果有人想查看代码,请访问https://github.com/MendelGusmao/CGI-for-LCD-Smartie

谢谢!

我不明白为什么不能让服务器在一个线程中侦听连接、处理数据并将数据放入队列,而计时器在另一个线程中将这些项目从队列中取出,然后通过popen()生成进程来处理队列数据。除非这里有我遗漏的细节,否则服务器将侦听的套接字(或管道、FIFO等)与libc运行时通过popen()内部打开的管道是分开的,因此服务器和计时器线程不会相互阻塞。您只需确保队列中有足够的空间来存储从服务器传入的数据,而不会溢出内存(即,如果这是一个高数据率的应用程序,并且数据传入的速度比处理的速度快得多,则最终会耗尽内存)。

最后,虽然通过muextes保护共享队列是一件好事,但如果您决定使用有界队列(即环形缓冲区),那么实际上对于您当前描述的单个生产者/消费者情况来说,这是不必要的。如果你决定使用一个无界队列,尽管有一些无锁算法,但它们非常复杂,因此用互斥锁保护像std::queue<T>这样的无界队列是绝对必须的。

我使用windows线程实现了几乎与您所描述的完全相同的东西。我让我的消费者等待一个事件HANDLE,当队列太长时,生产者会触发该事件。等待也有一个超时,因此如果队列填充得不够快,消费者仍将等待并处理队列。这是windows中的一项服务,因此使用了主线程。是的,访问共享对象将需要互斥对象。

所以我使用了两个线程(不包括main),一个互斥,一个共享对象。我认为更好的选择也是两个线程,因为它可以保持逻辑的清洁。主线程只是启动两个线程,然后等待(或者可以用于发出信号、控制、输出),另外两个线程只是在做自己的工作。