写入管道时出现中断系统调用错误

3

在我的用户空间Linux应用程序中,我有一个通过管道与主进程通信的线程。以下是代码:

static void _notify_main(int cond)
{
    int r;
    int tmp = cond;

    r = write( _nfy_fd, &tmp, sizeof(tmp) );
    ERROR( "write failed: %d. %s\n",  r, strerror(r) );
}

非常直白。它已经运行良好了相当一段时间。但最近,在程序经过一些压力测试后,写入调用将失败,并显示“中断的系统调用”错误。

奇怪的是,数据实际上没有问题地通过了管道。当然,我仍然想找出错误消息的原因并消除它。

谢谢。

2个回答

3

write(2) man page提到:

符合SVr4、4.3BSD、POSIX.1-2001标准。

在SVr4下,写操作可能会被中断并在任何时候返回EINTR,而不仅仅是在写入任何数据之前。

我猜你只是幸运地没有遇到过这种情况。

如果你只是搜索“中断的系统调用”,你会发现this thread,其中告诉你使用siginterrupt()自动重新启动write调用。


谢谢。正如我在原问题中所添加的,这在每次write()时发生,非常奇怪。 - lang2
我假设在压力测试中写入的数据非常大。也许你应该尝试将数据分块成合理大小的缓冲区,然后再写入这些缓冲区。 - blubb

0

来自http://www.gnu.org/

一个信号可以在等待I/O设备的I/O原语(如open或read)期间到达并被处理。如果信号处理程序返回,系统面临一个问题:接下来应该发生什么?

POSIX规定了一种方法:立即使原语失败。这种失败的错误代码是EINTR。这很灵活,但通常不方便。通常,使用信号处理程序的POSIX应用程序必须在每个可能返回它的库函数之后检查EINTR,以便再次尝试调用。经常程序员会忘记检查,这是一个常见的错误来源。

因此,您可以处理EINTR错误,还有另一种选择,您可以使用sigaction来建立一个信号处理程序,指定该处理程序应如何行为。使用SA_RESTART标志,从该处理程序返回将恢复原语;否则,从该处理程序返回将导致EINTR。

请参阅interrupted primitives


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接