gpt4 book ai didi

c - 在发送信号以中断系统调用时修复竞争条件

转载 作者:行者123 更新时间:2023-12-03 12:55:48 26 4
gpt4 key购买 nike

我有一个来自套接字的read() s的线程,并且我希望能够异步停止该线程。线程伪代码如下所示:

int needs_quit = 0;

void *thread_read(void *arg)
{
while(1)
{
if(needs_quit)
{
close(sock_fd);
return NULL;
}
int ret = read(sock_fd ...);
if(ret == EINTR) //we received an interrupt signal to stop
{
close(sock_fd);
return NULL;
}
//do stuff with read data
}
}

信号处理程序只需将 needs_quit设置为1。在大多数情况下,此代码将起作用。但是,如果信号在 if(needs_quit)之后和 read(sock_fd ...)之前到达,则 read()将不会被中断,并且线程将永远不会停止。解决此问题的最佳方法是什么?

我应该指出,我设法使用 pthread_cancel编写了一个可行的解决方案,但事实证明,由于兼容性问题,我不允许使用该解决方案。

预先感谢您的任何反馈。

最佳答案

正如您所发现的,仅仅翻转一个标志是不够的。我可以想到几种方法。

取消线程

不需要标志。

但是,正如您所指出的, pthread_cancel 不适用于您的环境,许多人认为它很容易被滥用。

限时read()
保持旗帜,并保持最小的耐心。

在短时间内将read替换为selectpoll可能就足够了。您是否在乎线程是否“立即”退出或在几秒钟内退出?
closeshutdown来自信号处理程序的套接字

没有标志,只是一个信号处理程序,该处理程序只是将close()shutdown插入套接字,从而唤醒read

在多线程环境中,关闭fds可能很危险,因为fd可以被另一个线程的openpipe或更多外来调用立即重新使用。例如,当信号处理程序关闭fd 5时,而另一个线程在pipe之前使用fd 5作为可读端来生成read,这是不好的。正如@R ..所提到的,shutdown可能有效或可能无效,但是,如果可行,这里是安全的。

使用自吸技巧

没有标志。相反,您的信号处理程序将一个字节写入一个非阻塞管道,并且您的线程select既位于有趣的套接字上,又位于管道的可读端。如果数据到达(或已经在等待)后者,则线程知道已发出信号。

使用 pselect

可以使用标志。

功能性的原子pselect和周到的信号屏蔽功能将为您提供可靠的EINTR信号传输指示。警告:glibc中此调用的早期版本不是原子的。

关于c - 在发送信号以中断系统调用时修复竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25799667/

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