gpt4 book ai didi

c - 如何唤醒正在 recvmsg() 中休眠的 pthread?

转载 作者:太空狗 更新时间:2023-10-29 11:37:09 27 4
gpt4 key购买 nike

我有一个使用 pthreads 的小 Unix 守护进程。一个线程循环运行,使用 recvmsg 读取网络数据包。当守护进程收到信号时,会设置一个标志,告诉所有线程跳出循环并退出。然而,“监听”线程从不检查标志,直到下一个数据包到达并且 recvmsg 返回,这可能需要一些时间。

使用 pthread_killSIGINT 传递给“监听”线程使其脱离 recvmsg,但它也会调用信号处理程序处理通过在控制台按 Ctrl+C 发送的中断。那是不需要的。另一种强制 recvmsg 提前返回的方法是关闭它正在监听的套接字,但我认为必须有更好的方法。你知道它是什么吗?

此守护程序仅在 Linux 上使用,如果它有所不同的话。

最佳答案

三个想法:

想法 #1:为什么不是另一个信号?信号 SIGUSR1SIGUSR2 仅用于用户定义的信号。如果您已经设置了信号处理程序并且通常熟悉它们的使用,这可能是最简单的方法。

想法 #2:按照其他人的建议发送一个虚拟数据包。

想法 #3:如果您真的想避免发送数据包,请尝试使用非阻塞 I/O,这样 recvmsg 就不会阻塞(参见 MSG_DONTWAIT)。

相反,调用 epoll |投票 |选择 以阻止套接字 recv 事件和另一个文件描述符。

所以循环看起来像这样:

while(1){
recvmsg();
do_stuff();
}

变成:

while(1){
wait_for_events();
if( /* FD used for cancellation is readable */ )
break;
else
recvmsg();
do_stuff();
}

其中 wait_for_eventsselectpollepoll_wait。设置等待列表以包括您的套接字和其他 fd,例如管道、unix 域套接字或 POSIX 消息队列(Linux 中的文件)。

要取消套接字读取器线程,请在取消文件对象上执行write。然后让读者检查从 poll/epoll/select 唤醒时是否能够读取该 fd。

如果处理 recvmsg 的事物有多个实例,您应该能够使用一个这样的文件来唤醒所有线程,如果使用 ,请确保使用水平触发而不是边缘触发>epoll.

如果您不确定使用这三个调用中的哪一个,我建议从 poll 开始,如果您已经非常了解它,则只使用 selectepoll 如果你知道你需要它的可扩展性。

关于c - 如何唤醒正在 recvmsg() 中休眠的 pthread?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29237539/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com