CTRL+c SIGINT 终止
CTRL+z SIGTSTP 停止进程
CTRL+\ SIGQUIT
SIGCONT 让进程后台继续运行,若改为前台运行,需要waitpid
终端KILL指令:
kill -s pid 将信号s发送至有pid指定进程
kill -l 可看到所有signal的编号(s的取值)
exec函数族:
关闭设置了执行时关闭标志的文件描述符
将所有原先要捕捉的信号都设置为默认动作
SIGKILL SIGSTOP 不能被忽略以及捕捉,因为这两个信号提供了终止或停止进程的可靠方法
使用signal捕获信号,在第一次捕获到信号后,该信号的处理方式恢复为默认SIG_DFL
可重入函数即异步信号安全的函数
不可重入:(1)使用静态存储区(书上说静态数据结构,一个意思,都是指系统分配的缓存区)
(2)使用malloc(动态缓存区)
(3)标准IO(理解:改写IO缓存区)
关于10_5 在信号处理程序中调用不可重入的函数getpwnam:
书中说结果不可知
实际运行中发现进程会阻塞在信号处理函数中的getpwnam处
使用strace -p pid指令 输出futex(0x7f75d1c70298, FUTEX_WAIT_PRIVATE, 2, NULL
没差,进程产生了死锁。
futex是实现信号量、互斥锁时用到的系统调用
僵尸进程和孤儿进程:
僵尸进程是指已经退出的子进程,但是父进程并没有调用wait或者waipid来获取子进程的退出状态(包括进程号the process ID,退出状态the termination status of the process,运行时间the amount of CPU time taken by the process等),子进程就会变成僵尸进程残留在系统中。
当父进程退出时,僵尸进程的父进程就变成了init,也就是孤儿进程,这时候才会得到释放
sigprocmask,三种模式,SIG_BLOCK,new|old ,添加新的阻塞信号;SIG_UNBLOCK ~new&old 接除对new中信号的阻塞 ;SIG_SETMASK new 将屏蔽设为new
sigpending 获得当前未决的信号,也就是在对某一个信号阻塞的过程中收到该信号
sigsuspend(const sigset_t * sigmask)将屏蔽字临时设置为sigmask,并进入pause阶段,在捕捉到一个信号并完成处理后函数返回,并将屏蔽字改回之前的值
关于apue3 10_22程序
1、屏蔽SIGINT后调用sigsuspend将屏蔽字设置为SIGUSR1(这时对SIGINT接触屏蔽)
随后终端键入CTRL+c,就会进入SIGINT的处理函数中
2、书中给出的结果,在进入SIGINT函数中会再次阻塞SIGINT,前文也说过signal的实现会阻塞当前信号处理函数所处理的信号
但是实测时发现SIGINT并没有被屏蔽
the original Unix systems, when a handler that was established using signal() was invoked by the delivery of a signal, the disposition of the signal would be reset to SIG_DFL, and the system did not block delivery of further instances of the signal.
abort()函数向进程发送SIGABRT,并且忽略进程对SIGABRT的阻塞
如果进程中捕捉SIGABRT,abort函数则发送两次SIGABRT信号,第一次完成用户定义的处理函数,恢复SIG_DFL,并再次发送终止进程
signal函数注册的一次性:
对于早期的信号(1~31),在使用signal函数注册信号捕捉函数时,调用过一次后就会重置为SIG_DFL
而使用sigaction函数注册的信号捕捉函数,在显示的改变它之前会一直保持有效,除非设置了struct sigaction的sa_flags成员的SA_RESETHAND选项。
SA_RESETHAND:在信号捕捉函数的入口处将此信号的动作重置为SIG_DFL(与signal动作相同),并清除SA_SIGINFO标志位,这些信号专指早期的不可靠信号