超时fwrite调用以防止阻塞

时间:2012-05-19 20:21:04

标签: c++ c blocking fwrite

是否有一种方法可以阻止fwrite阻塞,例如使用超时?

场景是这样的:我需要在网络上进行一次fwrite调用(因为我在很大程度上重用代码,我需要坚持使用它)。但是,如果我拔下网线,那么fwrite会阻塞。有解决方法吗?任何帮助/建议将不胜感激。

3 个答案:

答案 0 :(得分:3)

将基础文件描述符切换到非阻塞模式:

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

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

答案 1 :(得分:2)

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

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

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

答案 2 :(得分:1)

您可以设置信号处理程序并使用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全局变量的函数。 Google有一些例子。

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