如何在收到2个数据包后唤醒线程
我在我的项目中使用 libnetfilter_queue 。从 C 应用程序队列可以通过“队列文件描述符”访问。我有 5 个队列和 5 个线程来处理它们。我想要实现的是当队列中有 2 个数据包时唤醒线程。我想出了使用 select 函数和整数数组来指示每个队列中有多少个数据包排队的想法。使用 > 选择退出后0 代码我检查哪个队列已收到数据包并递增数组中的值,如果它大于 2,我会唤醒一个线程。一切都会好起来的,但是 select 表明队列有数据要读取,直到我调用 recv 为止,但我不能这样做,因为单独的线程应该处理这些数据包。有人知道如何解决这个问题吗?我知道我可以设置 SO_RCVLOWAT 但它不能解决我的问题,因为我不知道这两个数据包的大小。
I'm using libnetfilter_queue for my project. From C app queue is accessible by "queue file descriptor". I have 5 queues and 5 threads to handle them. What I want to achieve is to wake thread when there is exactly 2 packets in queue. I came up with idea to use select function and array of ints indicating how many packets were queued in each queue. After select exit with > 0 code I check which queue has received a packet and increment value in array, if it's bigger than 2 I wake up a thread. Everything would be fine, but select indicate that queue has data to read until I call recv and I can't do that because separate thread should handle these packets. Anyone has idea how to solve this issue? I know I can set SO_RCVLOWAT but it does not solve my problem, because I don't know what size will be those 2 packets.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
正如Tobu推荐的那样,epoll是一个更好的选择,并且它的性能比select更好。
然而,除非有人读取,否则大多数轮询函数都会指示存在事件(可用数据)。
如果可能,请使用以下模型:
使用epoll/select监视传入的数据唤醒工作线程。
在实际执行工作之前,让工作线程决定如何处理数据(一个数据包、两个或更多数据包)。
或者:
1个Reader线程-N个Worker线程:将使用epoll等待并读取所有传入的数据并将其发布到相应的worker线程的队列中。
一旦数据包数量达到阈值,唤醒工作线程(使用信号量)。
As recommended by Tobu, epoll is a better choice and it performs better than select.
However, most of these polling functions will indicate there is an event (data available) unless someone reads.
If possible use the following model:
Use epoll/select to watch for the incoming data wake up the worker thread.
Let the worker thread decide what to do with the data (one packet, two or more) before actually doing the work.
OR:
One Reader thread-N Worker threads: Will use epoll to wait and read all the incoming data and post it to the corresponding worker thread's queue.
Once the # of packet reaches the threshold, wake up the Worker thread (using a semaphore).
您正在寻找边缘触发的事件通知 - 当可用数据量发生变化时发送的通知。 epoll 的工作方式与使用 EPOLLET 标志时类似,默认情况下会重新设置通知,以便您会不断收到新数据包的通知。
请注意,如果两个 epoll_wait 调用之间有多个数据包到达,您只会收到一次通知。
You are looking for edge-triggered event notifications — notifications that are sent when the quantity of available data changes. epoll works like that when using the EPOLLET flag, and by default will rearm the notification so that you keep being notified of new packets.
Please note that you will be notified only once if several packets arrive between two epoll_wait calls.