linux c异步信号处理安全函数

  1. 基本概念

  • 信号是软件中断,提供了一种处理异步事件的方法。一个(具有合适权限的)进程能够向另一个进程发送信号。是进程间通讯的原始形式。可向其他进程发送信号,也可向自身发送信号。

  • 信号执行的时机是进程被调度执行时,或进程正在执行时。当进程不想被信号打断时,可将信号添加到进程的信号掩码中。

linux下的/proc/PID/status文件中的包含各种掩码字段,

  • linux改变信号默认处理行为的方法:sigal和sigaction,其处理的流程方法:

  • 用于发送信号的方法:kill。

#include <signal.h>
int kill (pid_t pid,int sig)

信号可以发送给指定进程,也可发送给当前调用kill的进程所在的进程组(包括调用kill进程)。还可发送给指定的进程组。最厉害的是可以发送给除init和本身之外的所有进程。其实现方法如下:

  1. 信号安全处理函数问题

信号的处理会打断当前的进程执行流程,安全问题引入场景是:多进程访问临界区问题包括:调用信号处理函数的进程和其他进程同时访问的问题(其他进程优先级比当前进程要高),信号打断当前进程进行执行流程导致的问题。这就要求信号处理函数要实现所谓的访问安全包括:禁止全局变量的访问、锁的获取和释放避免死锁的问题,任何有加锁操作的函数,除非它们特意使用了可重入锁,都应该被视为非异

步信号安全的,不应在信号处理函数中调用它们。不仅自己实现的处理函数要按照安全函数进行实现,在处理函数实现中调用的C库函数也要用安全的C库函数。

3未使用异步安全函数的案例

/lib/libpthread.so.0(+0x11110) [0x7fdf8cfde110]

/lib/libc.so.6(+0xf51db) [0x7fdf8be5f1db]

/lib/libc.so.6(+0xa9ed4) [0x7fdf8be13ed4]

test.exe(GetClock+0x51) [0x9a97a1]  // 信号处理函数中调用GetClock,其调用localtime_r导致线程自锁

test.exe(LinuxSignalHandler+0x160) [0x9469c0]  // 线程被信号中断

/lib/libpthread.so.0(+0x11110) [0x7fdf8cfde110]

/lib/libc.so.6(+0xa9ee0) [0x7fdf8be13ee0]  // localtime_r获取了时区保护锁

test.exe(GetClock+0x51) [0x9a97a1]  // 线程的GetClock调用localtime_r进行时间本地化转换

。。。。。。

程序的正在执行GetClock函数时被信号中断,随后在信号处理函数中再次调用GetClock函数localtime_r获取时区保护锁,导致该线程自锁。

4.哪些C库函数是异步安全函数

可通过man 7 signal-safety 命令来得到对应glibc版本的异步信号安全函数清单。

附录:异步信号安全函数清单(glibc-2.28)

函数名后括号中的数字,表示在linux manual中的分组。比如abort(3), 表示可以通过shell命令man 3 abort 来查看这个接口函数的使用说明。

A

abort(3) accept(2) access(2) aio_error(3) aio_return(3) aio_suspend(3) alarm(2)

W

wait(2) waitpid(2) wcpcpy(3) wcpncpy(3) wcscat(3) schr(3) wcscmp(3) wcscpy(3) wcscspn(3) wcslen(3) wcsncat(3) wcsncmp(3) wcsncpy(3) wcsnlen(3) wcspbrk(3) wcsrchr(3) wcsspn(3) wcsstr(3) wcstok(3) wmemchr(3) wmemcmp(3) wmemcpy(3) wmemmove(3) wmemset(3) write(2)

U

umask(2) uname(2) unlink(2) unlinkat(2) utime(2) utimensat(2) utimes(2)

T

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)

S

select(2) em_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) signal(2) sigpause(3) sigpending(2) sigprocmask(2) sigqueue(2) sigset(3) sigsuspend(2) sleep(3) sockatmark(3) socket(2) socketpair(2) stat(2) stpcpy(3) stpncpy(3) strcat(3) strchr(3) strcmp(3) strcpy(3) strcspn(3) strlen(3) strncat(3) strncmp(3) strncpy(3) strnlen(3) strpbrk(3) strrchr(3) strspn(3) strstr(3) strtok_r(3) symlink(2) symlinkat(2)

R

raise(3) read(2) readlink(2) readlinkat(2) recv(2) recvfrom(2) recvmsg(2) rename(2) renameat(2) rmdir(2)

P

pause(2) pipe(2) poll(2) posix_trace_event(3) pselect(2) pthread_kill(3) pthread_self(3) pthread_sigmask(3)

O

open(2) openat(2)

N

ntohl(3) ntohs(3)

M

memccpy(3) memchr(3) memcmp(3) memcpy(3) memmove(3) memset(3) mkdir(2) mkdirat(2) mkfifo(3) mkfifoat(3) mknod(2) mknodat(2)

L

link(2) linkat(2) listen(2) longjmp(3) lseek(2) lstat(2)

K

kill(2)

H

htonl(3) htons(3)

G

getegid(2) geteuid(2) getgid(2) getgroups(2) getpeername(2) getpgrp(2) getpid(2) getppid(2) getsockname(2) getsockopt(2) getuid(2)

F

faccessat(2) fchdir(2) fchmod(2) fchmodat(2) fchown(2) fchownat(2) fcntl(2) fdatasync(2) fexecve(3) ffs(3) fork(2) fstat(2) fstatat(2) fsync(2) ftruncate(2) futimens(3)

E

execl(3) execle(3) execv(3) execve(2) _exit(2) _Exit(2)

D

dup(2) dup2(2)

C

cfgetispeed(3) cfgetospeed(3) cfsetispeed(3) cfsetospeed(3) chdir(2) chmod(2) chown(2) clock_gettime(2) close(2) connect(2) creat(2)

B

bind(2)

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值