收到2个数据包后如何唤醒线程

Posted

技术标签:

【中文标题】收到2个数据包后如何唤醒线程【英文标题】:How to wake a thread after receiving 2 packets 【发布时间】:2010-11-23 20:36:32 【问题描述】:

我正在为我的项目使用 libnetfilter_queue。从 C 应用程序队列可通过“队列文件描述符”访问。我有 5 个队列和 5 个线程来处理它们。我想要实现的是当队列中正好有 2 个数据包时唤醒线程。我想出了使用选择函数和整数数组来指示每个队列中有多少数据包排队的想法。在使用 > 0 代码选择退出后,我检查哪个队列已收到数据包并在数组中增加值,如果它大于 2,我会唤醒一个线程。一切都会好起来的,但是 select 表明队列有数据要读取,直到我调用 recv 并且我不能这样做,因为单独的线程应该处理这些数据包。任何人都知道如何解决这个问题?我知道我可以设置 SO_RCVLOWAT 但它不能解决我的问题,因为我不知道这 2 个数据包的大小。

【问题讨论】:

你为什么需要这样的东西? 【参考方案1】:

正如 Tobu 所推荐的,epoll 是一个更好的选择,并且它的性能比 select 更好。 但是,这些轮询函数中的大多数将指示存在事件(数据可用),除非有人阅读。 如果可能,请使用以下模型: 使用 epoll/select 观察传入的数据唤醒工作线程。 让工作线程在实际执行工作之前决定如何处理数据(一个数据包、两个或更多数据包)。

或者: 一个Reader线程-N个Worker线程:会使用epoll等待并读取所有传入的数据,并post到对应的worker线程的队列中。 一旦包的数量达到阈值,唤醒工作线程(使用信号量)。

【讨论】:

【参考方案2】:

您正在寻找边缘触发的事件通知——当可用数据量发生变化时发送的通知。 epoll 在使用 EPOLLET 标志时的工作方式与此类似,默认情况下会重新启动通知,以便您不断收到新数据包的通知。

请注意,如果在两次 epoll_wait 调用之间有多个数据包到达,您只会收到一次通知。

【讨论】:

我明白你的意思。如果我在 epoll_wait 调用之间花费了太多时间,并且在那段时间收到了超过 1 个数据包,我无法确定收到了多少。感谢您提供这些信息 真的是当可用数据量发生变化时 还是当它从空变为非空(对于接收缓冲区)? 我很确定是前者:每当数据包到达时。内核代码只是在调用 ep_poll_callback 时设置一个标志,并且不跟踪当时缓冲区是否已满。

以上是关于收到2个数据包后如何唤醒线程的主要内容,如果未能解决你的问题,请参考以下文章

为啥线程没有在线程池中重用?

业务需求:主线程重组数据后,一份转发至其他程序,一份存储本地记录

Java实现远程主机唤醒 (WOL)

Java实现远程主机唤醒 (WOL)

已终止的应用程序未使用 iBeacon 数据包唤醒

TCP检测到丢包后是不是还发送新的数据包