可重入
被不同的控制流程调用,有可能在第一次调用还没返回时就再次进入该函数这称为重入,访问一个全局对象,有可能因为重入而造成错乱,像这样的函数称为不可重入函数,反之,如果一个函数只访问自己的局部变量或参数,则称为可重入(Reentrant)函数。
不可重入的原因:
- 已知它们使用静态数据结构
- 它们调用malloc和free因为malloc通常会为所分配的存储区维护一个链接表,而插入执行信号处理函数的时候,进程可能正在修改此链接表。
- 它们是标准IO函数。因为标准IO库的很多实现都使用了全局数据结构
一个信号处理器中中能在调用的函数
accept | fchmod | lseek | sendto | stat |
access | fchown | lstat | setgid | symlink |
aio_error | fcntl | mkdir | setpgid | sysconf |
aio_return | fdatasync | mkfifo | setsid | tcdrain |
aio_suspend | fork | open | setsockopt | tcflow |
alarm | fpathconf | pathconf | setuid | tcflush |
bind | fstat | pause | shutdown | tcgetattr |
cfgetispeed | fsync | pipe | sigaction | tcgetpgrp |
cfgetospeed | ftruncate | poll | sigaddset | tcsendbreak |
cfsetispeed | getegid | posix_trace_event | sigdelset | tcsetattr |
cfsetospeed | geteuid | pselect | sigemptyset | tcsetpgrp |
chdir | getgid | raise | sigfillset | time |
chmod | getgroups | read | sigismenber | timer_getoverrun |
chown | getpeername | readlink | signal | timer_gettime |
clock_gettime | getpgrp | recv | sigpause | timer_settime |
close | getpid | recvfrom | sigpending | times |
connect | getppid | recvmsg | sigprocmask | umask |
creat | getsockname | rename | sigqueue | uname |
dup | getsockopt | rmdir | sigset | unlink |
dup2 | getuid | select | sigsuspend | utime |
execle | kill | sem_post | sleep | wait |
execve | link | send | socket | waitpid |
_Exit & _exit | listen | sendmsg | socketpair | write |
异步信号安全
所有的I/O函数和pthread_XXX函数都不可在信号处理程序中调用,Unix网络编程2中所有的IPC函数只有sem_post,read,write(read和write只作用于管道和FIFO时)可以