SIGNAL-SAFETY - Linux手册页
时间:2019-08-20 18:02:02 来源:igfitidea点击:
Linux程序员手册 第7部分
更新日期: 2020-06-09
名称
信号安全-异步信号安全功能
说明
异步信号安全功能是可以从信号处理程序中安全调用的功能。许多功能不是异步信号安全的。特别是,非重入函数通常从信号处理程序中调用是不安全的。
当人们考虑实现stdio库的实现时,可以很快理解使函数不安全的各种问题,因为stdio库的所有函数都不是异步信号安全的。
在文件上执行缓冲的I / O时,stdio函数必须维护一个静态分配的数据缓冲区以及相关的计数器和索引(或指针),这些计数器和索引记录数据量和缓冲区中的当前位置。假设主程序在对stdio函数(例如printf(3))的调用中,缓冲区和相关变量已部分更新。如果在那一刻,该程序被也调用printf(3)的信号处理程序中断,则对printf(3)的第二次调用将对不一致的数据进行操作,结果无法预测。
为避免功能不安全的问题,有两种可能的选择:
- 1.
- 确保(a)信号处理程序仅调用异步信号安全函数,并且(b)信号处理程序本身相对于主程序中的全局变量是可重入的。
- 2.
- 当调用不安全的函数或对也由信号处理程序访问的全局数据进行操作时,在主程序中阻止信号传递。
通常,第二选择在任何复杂的程序中都是困难的,因此采用第一选择。
POSIX.1指定实现必须使异步信号安全的一组功能。 (一个实现可以提供附加功能的安全实现,但这不是标准所必需的,其他实现可能不能提供相同的保证。)
通常,函数是异步信号安全的,因为它是可重入的,或者因为它对于信号而言是原子的(即,其执行不能被信号处理程序中断)。
下表显示了POSIX.1要求的异步信号安全功能集。 POSIX.1-2001中要求未另行说明的功能必须是异步信号安全的;该表详细介绍了后续标准中的更改。
| Function | Notes |
| abort(3) | Added in POSIX.1-2001 TC1 |
| accept(2) | |
| access(2) | |
| aio_error(3) | |
| aio_return(3) | |
| aio_suspend(3) | See notes below |
| alarm(2) | |
| bind(2) | |
| cfgetispeed(3) | |
| cfgetospeed(3) | |
| cfsetispeed(3) | |
| cfsetospeed(3) | |
| chdir(2) | |
| chmod(2) | |
| chown(2) | |
| clock_gettime(2) | |
| close(2) | |
| connect(2) | |
| creat(2) | |
| dup(2) | |
| dup2(2) | |
| execl(3) | Added in POSIX.1-2008; see notes below |
| execle(3) | See notes below |
| execv(3) | Added in POSIX.1-2008 |
| execve(2) | |
| _exit(2) | |
| _Exit(2) | |
| faccessat(2) | Added in POSIX.1-2008 |
| fchdir(2) | Added in POSIX.1-2008 TC1 |
| fchmod(2) | |
| fchmodat(2) | Added in POSIX.1-2008 |
| fchown(2) | |
| fchownat(2) | Added in POSIX.1-2008 |
| fcntl(2) | |
| fdatasync(2) | |
| fexecve(3) | Added in POSIX.1-2008 |
| ffs(3) | Added in POSIX.1-2008 TC2 |
| fork(2) | See notes below |
| fstat(2) | |
| fstatat(2) | Added in POSIX.1-2008 |
| fsync(2) | |
| ftruncate(2) | |
| futimens(3) | Added in POSIX.1-2008 |
| getegid(2) | |
| geteuid(2) | |
| getgid(2) | |
| getgroups(2) | |
| getpeername(2) | |
| getpgrp(2) | |
| getpid(2) | |
| getppid(2) | |
| getsockname(2) | |
| getsockopt(2) | |
| getuid(2) | |
| htonl(3) | Added in POSIX.1-2008 TC2 |
| htons(3) | Added in POSIX.1-2008 TC2 |
| kill(2) | |
| link(2) | |
| linkat(2) | Added in POSIX.1-2008 |
| listen(2) | |
| longjmp(3) | Added in POSIX.1-2008 TC2; see notes below |
| lseek(2) | |
| lstat(2) | |
| memccpy(3) | Added in POSIX.1-2008 TC2 |
| memchr(3) | Added in POSIX.1-2008 TC2 |
| memcmp(3) | Added in POSIX.1-2008 TC2 |
| memcpy(3) | Added in POSIX.1-2008 TC2 |
| memmove(3) | Added in POSIX.1-2008 TC2 |
| memset(3) | Added in POSIX.1-2008 TC2 |
| mkdir(2) | |
| mkdirat(2) | Added in POSIX.1-2008 |
| mkfifo(3) | |
| mkfifoat(3) | Added in POSIX.1-2008 |
| mknod(2) | Added in POSIX.1-2008 |
| mknodat(2) | Added in POSIX.1-2008 |
| ntohl(3) | Added in POSIX.1-2008 TC2 |
| ntohs(3) | Added in POSIX.1-2008 TC2 |
| open(2) | |
| openat(2) | Added in POSIX.1-2008 |
| pause(2) | |
| pipe(2) | |
| poll(2) | |
| posix_trace_event(3) | |
| pselect(2) | |
| pthread_kill(3) | Added in POSIX.1-2008 TC1 |
| pthread_self(3) | Added in POSIX.1-2008 TC1 |
| pthread_sigmask(3) | Added in POSIX.1-2008 TC1 |
| raise(3) | |
| read(2) | |
| readlink(2) | |
| readlinkat(2) | Added in POSIX.1-2008 |
| recv(2) | |
| recvfrom(2) | |
| recvmsg(2) | |
| rename(2) | |
| renameat(2) | Added in POSIX.1-2008 |
| rmdir(2) | |
| select(2) | |
| sem_post(3) | |
| send(2) | |
| sendmsg(2) | |
| sendto(2) | |
| setgid(2) | |
| setpgid(2) | |
| setsid(2) | |
| setsockopt(2) | |
| setuid(2) | |
| shutdown(2) | |
| sigaction(2) | |
| sigaddset(3) | |
| sigdelset(3) | |
| sigemptyset(3) | |
| sigfillset(3) | |
| sigismember(3) | |
| siglongjmp(3) | Added in POSIX.1-2008 TC2; see notes below |
| signal(2) | |
| sigpause(3) | |
| sigpending(2) | |
| sigprocmask(2) | |
| sigqueue(2) | |
| sigset(3) | |
| sigsuspend(2) | |
| sleep(3) | |
| sockatmark(3) | Added in POSIX.1-2001 TC2 |
| socket(2) | |
| socketpair(2) | |
| stat(2) | |
| stpcpy(3) | Added in POSIX.1-2008 TC2 |
| stpncpy(3) | Added in POSIX.1-2008 TC2 |
| strcat(3) | Added in POSIX.1-2008 TC2 |
| strchr(3) | Added in POSIX.1-2008 TC2 |
| strcmp(3) | Added in POSIX.1-2008 TC2 |
| strcpy(3) | Added in POSIX.1-2008 TC2 |
| strcspn(3) | Added in POSIX.1-2008 TC2 |
| strlen(3) | Added in POSIX.1-2008 TC2 |
| strncat(3) | Added in POSIX.1-2008 TC2 |
| strncmp(3) | Added in POSIX.1-2008 TC2 |
| strncpy(3) | Added in POSIX.1-2008 TC2 |
| strnlen(3) | Added in POSIX.1-2008 TC2 |
| strpbrk(3) | Added in POSIX.1-2008 TC2 |
| strrchr(3) | Added in POSIX.1-2008 TC2 |
| strspn(3) | Added in POSIX.1-2008 TC2 |
| strstr(3) | Added in POSIX.1-2008 TC2 |
| strtok_r(3) | Added in POSIX.1-2008 TC2 |
| symlink(2) | |
| symlinkat(2) | Added in POSIX.1-2008 |
| tcdrain(3) | |
| tcflow(3) | |
| tcflush(3) | |
| tcgetattr(3) | |
| tcgetpgrp(3) | |
| tcsendbreak(3) | |
| tcsetattr(3) | |
| tcsetpgrp(3) | |
| time(2) | |
| timer_getoverrun(2) | |
| timer_gettime(2) | |
| timer_settime(2) | |
| times(2) | |
| umask(2) | |
| uname(2) | |
| unlink(2) | |
| unlinkat(2) | Added in POSIX.1-2008 |
| utime(2) | |
| utimensat(2) | Added in POSIX.1-2008 |
| utimes(2) | Added in POSIX.1-2008 |
| wait(2) | |
| waitpid(2) | |
| wcpcpy(3) | Added in POSIX.1-2008 TC2 |
| wcpncpy(3) | Added in POSIX.1-2008 TC2 |
| wcscat(3) | Added in POSIX.1-2008 TC2 |
| wcschr(3) | Added in POSIX.1-2008 TC2 |
| wcscmp(3) | Added in POSIX.1-2008 TC2 |
| wcscpy(3) | Added in POSIX.1-2008 TC2 |
| wcscspn(3) | Added in POSIX.1-2008 TC2 |
| wcslen(3) | Added in POSIX.1-2008 TC2 |
| wcsncat(3) | Added in POSIX.1-2008 TC2 |
| wcsncmp(3) | Added in POSIX.1-2008 TC2 |
| wcsncpy(3) | Added in POSIX.1-2008 TC2 |
| wcsnlen(3) | Added in POSIX.1-2008 TC2 |
| wcspbrk(3) | Added in POSIX.1-2008 TC2 |
| wcsrchr(3) | Added in POSIX.1-2008 TC2 |
| wcsspn(3) | Added in POSIX.1-2008 TC2 |
| wcsstr(3) | Added in POSIX.1-2008 TC2 |
| wcstok(3) | Added in POSIX.1-2008 TC2 |
| wmemchr(3) | Added in POSIX.1-2008 TC2 |
| wmemcmp(3) | Added in POSIX.1-2008 TC2 |
| wmemcpy(3) | Added in POSIX.1-2008 TC2 |
| wmemmove(3) | Added in POSIX.1-2008 TC2 |
| wmemset(3) | Added in POSIX.1-2008 TC2 |
| write(2) |
笔记:
- *
- POSIX.1-2001和POSIX.1-2001 TC2要求函数fpathconf(3),pathconf(3)和sysconf(3)是异步信号安全的,但此要求在POSIX.1-2008中已删除。
- *
- 如果信号处理程序中断了不安全功能的执行,并且该处理程序通过调用longjmp(3)或siglongjmp(3)终止,并且程序随后调用了一个不安全功能,则该程序的行为是不确定的。
- *
- POSIX.1-2001 TC1阐明,如果应用程序从信号处理程序调用fork(2),而pthread_atfork(3)注册的任何fork处理程序都调用了一个异步信号安全的函数,则该行为是不确定的。该标准的未来修订版可能会从异步信号安全功能列表中删除fork(2)。
- *
- 调用作为取消点的函数并嵌套在延迟取消区域上的异步信号处理程序可能会触发其行为好像已发生异步取消的取消,并且可能导致应用程序状态变得不一致。
Deviations in the GNU C library
GNU C库中发生以下与标准的已知偏差:
- *
- 在glibc 2.24之前,execl(3)和execle(3)在内部使用realloc(3),因此不是异步信号安全的。此问题已在glibc 2.24中修复。
- *
- aio_suspend(3)的glibc实现不是异步信号安全的,因为它在内部使用了pthread_mutex_lock(3)。
出版信息
这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/。

