4

有没有一种方法可以防止 fwrite 阻塞,比如使用超时?

场景是这样的:我需要在网络上进行 fwrite 调用(因为我主要重用代码,所以我需要坚持下去)。但是,如果我拔掉网线,fwrite 会阻塞。有解决方法吗?任何帮助/建议将不胜感激。

4

3 回答 3

5

将底层文件描述符切换到非阻塞模式:

int fd = fdnum(stream);
int f = fcntl(fd, F_GETFL, 0);
f |= O_NONBLOCK;
fcntl(fd, F_SETFL, f);

在此之后,如果文件描述符尚未准备好写入,则调用fwrite()将立即返回并设置为 EAGAIN。errno在循环中调用它并使用 sleeps,您可以轻松实现所需的任何超时行为。

于 2012-05-19T20:49:40.800 回答
4

这应该与@Alexander Bakulin 的建议具有相同的效果,但要短一些。

int fd = fdnum(stream);
int ioctl( fd, FIONBIO, 1 );

参考: http: //oss.org.cn/ossdocs/gnu/linux/syscalls_17.html

于 2012-05-19T21:27:37.033 回答
2

您可以设置一个信号处理程序并使用alarm()系统调用来安排该信号的传递,这将中断fwrite()调用。典型用法如下所示:

signal(SIGALRM, handle_sigalrm);
received_alarm = 0;
alarm(10);
...some blocking operation...
alarm(0); // cancel the alarm.
if (received_alarm) {
  // command timed out
} else {
  // command completed successfully
}

这假定这是一个在调用时设置全局变量handle_sigalrm()的函数。谷歌有一些例子。received_alarm

这绝对不是处理此问题的最佳方法,但如果您被迫使用fwrite(). 更好的解决方案是使用select()orpoll()循环和非阻塞套接字,但这可能需要对代码进行大量重新设计。

于 2012-05-19T20:39:31.347 回答