阻塞函数
一些系统调用可能会阻塞相当长的一段时间(或永远阻塞),例如以下这些:
• read(2) from files that can block (pipes, networks, terminals)
• write(2) to the same sort of files
• open(2) of a device that waits until a condition occurs (for example, a modem)
• pause(3), which purposefully puts a process to sleep until a signal occurs
• certain ioctl(2)s
• certain IPC functions
• file- or record-locking mechanisms
如果信号处理函数在系统调用在阻塞时被调用,那么:
-
(该系统调用被强制终止)the call may be forced to terminate with the error EINTR
-
该系统调用可能提前返回(the call may return with a data transfer shorter than requested)
-
在信号处理函数返回时,该系统调用自动重启
-
发生哪种行为取决于接口以及是否使用SA_RESTART标志建立了信号处理程序(请参见sigaction(2))
Which of these behaviors occurs depends on the interface and whether or not the signal handler was established using the SA_RESTART flag (see sigaction(2)) -
其中大部分是特定于操作系统的,在某些平台上,只有某些调用可以重新启动,而其他调用在中断时总是会失败
much of this is OS specific, and on some platforms only some calls may be restarted, while others always will fail when interrupted
注意:会存在可移植性的问题,应该尽量避免在信号处理函数中使用这些(低速)阻塞函数
- 只有保证异步信号安全的函数才能安全地在信号处理程序中使用(Only functions that are guaranteed to be async-signal-safe can safely be used in signal handlers)
- POSIX保证了一组这样的异步信号安全功能。 不同的操作系统(版本)可能会添加额外的。POSIX guarantees a set of such async-signal-safe functions; different OS (versions) may add others.
- 有些异步安全函数可能会设置 errno, 最好保存并重置
- 低速系统调用可能会失败、重启、提前返回。
这在很大程度上取决于操作系统风格和版本的差异
这会带来移植性方面的问题。Interrupted system calls may fail, return short, or be restarted, again very much subject to variance across OS flavors and versions.