简体   繁体   English

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

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

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. 处理队列后,外部进程将通过popen打开,这意味着popen将阻塞计时器,直到进程结束。

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. 如果我错了,请纠正我,但是由于服务器和计时器都链接到同一个io_service,因此如果服务器接收到数据,它将以某种方式阻止io_service继续进行下一个事件,反之亦然,如果a队列中的进程正在执行。

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. 我在考虑基于boost :: thread的解决方案,但是由于我从未使用过线程,因此我不确定应该使用哪种体系结构。 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. 两个线程-一个用于计时器,一个用于服务器,每个线程使用其自己的io_service一个线程-一个用于具有自己的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 如果有人想看一下代码,请访问https://github.com/MendelGusmao/CGI-for-LCD-Smartie。

Thanks! 谢谢!

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. 我不明白为什么您不能让服务器监听连接,处理数据并将数据放在一个线程的队列中,而您的计时器却将这些项目从另一个线程的队列中取出,然后通过popen()来处理队列数据。 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. 除非我错过了一个细节,否则服务器将监听的套接字(或管道,FIFO等)与libc运行时将通过popen()在内部打开的管道是分开的,因此您的服务器线程和计时器线程不会互相阻塞。 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 (ie, 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 (ie, a ring-buffer). 最后,虽然通过muextes保护共享队列是一件好事,但实际上仅对于单个生产者/消费者情况就没有必要,例如您当前正在描述是否决定使用有界队列(即环形缓冲区)。 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. 如果您决定一个无界队列,尽管那里有一些无锁算法,但是它们很复杂,因此绝对必须使用互斥量来保护像std::queue<T>这样的无界队列。

I have implemented almost the exact thing you have described using windows threads. 我已经使用Windows线程实现了几乎所描述的确切内容。 I had my consumer wait on an event HANDLE which is fired by the producer when the queue gets too long. 我让我的使用者等待事件HANDLE ,当队列过长时,该事件由生产者触发。 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. 这是Windows中的一项服务,因此使用了主线程。 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. 因此,我使用了两个线程(不包括主线程),1个互斥锁,1个共享对象。 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. 主线程只是启动两个线程,然后等待(或可以用于发信号,控制,输出),而其他两个线程只是在做自己的工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM