C fopen/fdopen在断开的网络共享或删除的usb设备上冻结

C fopen/fdopen在断开的网络共享或删除的usb设备上冻结,c,linux,fopen,C,Linux,Fopen,我正在用C语言为嵌入式linux设备构建一个后台服务。 每小时从网络共享或usb设备读取一个文件, 但如果网络或usb设备已拔出,fopen将永远不会返回 服务冻结。我不允许使用诸如pthread或fork之类的异步方法来读取该文件,因此我正在寻找一个带有超时或非阻塞的解决方案,以测试该文件(或设备)是否可用 下面的代码示例在fopen/fdopen上冻结 FILE* f = fopen("/path/to/file", "r"); //freezes if device not availab

我正在用C语言为嵌入式linux设备构建一个后台服务。 每小时从网络共享或usb设备读取一个文件, 但如果网络或usb设备已拔出,fopen将永远不会返回 服务冻结。我不允许使用诸如pthread或fork之类的异步方法来读取该文件,因此我正在寻找一个带有超时或非阻塞的解决方案,以测试该文件(或设备)是否可用

下面的代码示例在fopen/fdopen上冻结

FILE* f = fopen("/path/to/file", "r"); //freezes if device not available;
if(f)
{
    < .. read file .. >
    fclose(f);
}

////////////////////////////////////////////

FILE* f = NULL;
int fd  = open("/path/to/file", O_RDONLY|O_NONBLOCK);
if(fd>=0)
{
    f= fdopen(fd, "r");//freezes if device not available
}

if(f)
{
    < .. read file .. >
    fclose(f);
}
else
{
    if(fd>=0){close(fd);}
}
FILE*f=fopen(“/path/to/FILE”,“r”)//如果设备不可用,则冻结;
如果(f)
{
<…读取文件..>
fclose(f);
}
////////////////////////////////////////////
文件*f=NULL;
int fd=open(“/path/to/file”,O|RDONLY | O|NONBLOCK);
如果(fd>=0)
{
f=fdopen(fd,“r”);//如果设备不可用,则冻结
}
如果(f)
{
<…读取文件..>
fclose(f);
}
其他的
{
如果(fd>=0){close(fd);}
}
编辑:
答案并不能解决我的问题。我确实知道发生这种情况的原因,但服务不能等待无响应的设备。如上所述,我需要一个非阻塞解决方案或一个超时。

可能重复使用空正文信号处理程序和一个超时信号,以便
open()
/
fopen()
/
fdopen()
在经过足够的时间后以
errno==EINTR
失败。我举了一个CC0/Public Domain的例子,如果您希望只使用一个信号同时超时。听起来您的进程可能陷入了不间断睡眠(也称为磁盘等待)。如果是这种情况,
ps
将显示
D
的状态。无法使用信号纠正这种情况-即使是
SIGKILL
也不会在这种状态下终止进程。您无法修复用户空间中的问题。考虑到单个线程的约束,您甚至无法解决此问题。相反,您必须找到一种方法说服相关驱动程序(可能是文件系统驱动程序或USB设备驱动程序)放弃该操作,而不是永远重试。例如,对于NFS,您可以调整装载选项。我尝试用@Nominal Animal之类的信号中断fopen,但没有成功。目前,cronjob用于测试服务是否无响应,但这也不是长期解决方案。