gpt4 book ai didi

c++ - 取消卡在 epoll_wait 上的线程

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:14:41 38 4
gpt4 key购买 nike

我正在使用 C++ 和 pthreads 进行一些事件处理。我有一个从我定义的事件队列中读取的主线程,以及一个填充事件队列的工作线程。队列当然是线程安全的。

工作线程有一个文件描述符列表,并创建一个 epoll 系统调用来获取这些文件描述符上的事件。它使用 epoll_wait 等待 fd 上的事件。

现在是问题。假设我想干净地终止我的应用程序,我怎样才能正确地取消工作线程? epoll_wait 不是pthread(7)的取消点之一因此它无法对 pthread_cancel 做出正确 react 。

工作线程 main() 看起来像这样

while(m_WorkerRunning) {
epoll_wait(m_EpollDescriptor, events, MAXEVENTS, -1);
//handle events and insert to queue
}

当线程启动时,m_WorkerRunning 设置为 true,看起来我可以通过设置 m_WorkerRunning< 中断线程 从主线程设置为 false。问题是 epoll_wait 理论上可以永远等待。

我想到的其他解决方案是:我可以等待 X 个时隙,而不是永远等待 (-1),然后正确处理无事件情况,如果 m_WorkerRunning == false 则退出循环并干净地终止工作线程。主线程然后将 m_WorkerRunning 设置为 false,并休眠 X。但是我不确定这种 epoll_wait 的性能,也不确定正确的 X 是什么? 500毫秒? 1秒? 10 秒?

我想听听一些有经验的建议!

更多相关信息:我正在等待事件的 fd 是 /dev/input 中的设备,所以从技术上讲,我正在做某种输入子系统。目标操作系统是基于 ARM 架构的 Linux(最新内核)。

谢谢!

最佳答案

alk 上面的回答 几乎是正确的。然而,差异是非常危险的。

如果您要发送信号以唤醒 epoll_wait永远不要使用 epoll_wait。您必须使用 epoll_pwait,否则您可能会遇到 epoll 永远不会醒来的情况。

信号异步到达。如果您的 SIGUSR1 在您检查了关闭程序之后到达,但在您的循环返回到 epoll_wait 之前,那么信号不会中断等待(因为没有) ,但程序也不会退出。

这可能非常有可能,也可能极不可能,具体取决于循环花费的时间与等待时间的关系,但无论如何这都是一个错误。

alk 的答案的另一个问题是它不检查等待被中断的原因。这可能有多种原因,有些与您的退出无关。

有关更多信息,请参阅 pselect 的手册页. epoll_pwait 以类似的方式工作。

此外,永远不要使用kill 向线程发送信号。使用 pthread_kill反而。 kill 在发送信号时的行为充其量是未定义的。无法保证正确的线程会收到它,这可能会导致不相关的系统调用被中断,或者什么也不会发生。

关于c++ - 取消卡在 epoll_wait 上的线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18614168/

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