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

发布于 2025-01-03 20:31:38 字数 592 浏览 0 评论 0原文

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

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

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

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

以两种方式都必须共享队列(一个简单的映射),所以我想我会在互斥体和其他事情上遇到一些麻烦

如果有人想看一下代码,它位于https://github.com/MendelGusmao/CGI-for-LCD-Smartie

谢谢!

My project has a queue, a server and a timer. The server receives data and puts it in the queue and the timer process the queue. When the queue is processed, external processes are open with popen, which means that popen will block the timer until a process has ended.

Correct me if I'm wrong, but as both server and timer are linked to the same io_service, if the server receives data, it will somehow block io_service from proceeding to the next event, and the vice-versa is the timer blocking if a process in the queue is being executed.

I'm thinking in a solution based on boost::thread but I'm not sure of what architecture should I use as I never used threads. My options are:

Two threads - one for the timer and one for the server, each one using its own io_service
One thread - one for the timer with its own io_service. the server remains in main process

In both ways the queue (a simple map) must be shared, so I think I'll have some trouble with mutexes and other things

If someone wants to take a look at the code, it is at https://github.com/MendelGusmao/CGI-for-LCD-Smartie

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

羅雙樹 2025-01-10 20:31:38

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

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

I don't see why you can't have your server listening for connections, processing data, and placing that data in the queue in one thread while your timer takes those items out of the queue in another thread and then spawns processes via popen() to process the queue data. Unless there is a detail here that I've missed, the socket that the server will be listening on (or pipe, FIFO, etc.), is separate from the pipe that will be internally opened by the libc runtime via popen(), so your server and timer threads won't be blocking each other. You'll simply have to make sure that you have enough space in the queue to store the data coming in from the server without overflowing memory (i.e., if this is a high-data-rate application, and data is coming in much faster than it's being processed, you'll eventually run out of memory).

Finally, while guarding a shared queue via muextes is a good thing, it's actually unnecessary for only a single producer/consumer situation like you're currently describing if you decide to use a bounded queue (i.e., a ring-buffer). If you decide on an unbounded queue, while there are some lockless algorithms out there, they're pretty complex, and so guarding an unbounded queue like std::queue<T> with a mutex is an absolute must.

素染倾城色 2025-01-10 20:31:38

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

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

I have implemented almost the exact thing you have described using windows threads. I had my consumer wait on an event HANDLE which is fired by the producer when the queue gets too long. There was a timeout on the wait as well so that if the queue was not filled fast enough the consumer would still wait and process the queue. It was a service in windows so the main thread was used for that. And yes, mutexes will be required to access the shared object.

So I used two threads (not including the main), 1 mutex, 1 shared object. I think your better option is also two threads as it keeps the logic cleaner. The main thread just starts the two threads and then waits (or can be used for signalling, control, output), and the two other threads are just doing their own jobs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文