并发编程把我整崩溃了。这篇文章把相关内容捋一下。
1. 异常类型:中断、陷阱、故障、终止。中断是异步,其他三个是同步。中断一般是来自io,陷阱用来调用内核指令。
linux有256种异常,前32种是intel定义的。每个异常有异常号。
2. Unix系统级函数遇到错误时,通常返回-1,并设置全局整数变量errno来表示出什么错了。
创建进程用fork,加载用evecve。
进程有三个状态,运行、停止、终止。
3. waitpid,用来回收进程。
pid_t waitpid(pid_t pid, int *statusp, int options).
pid>0,等待特定进程,-1表示所有子进程
statusp如果非空,*statusp=导致返回的子进程的状态信息。status不能直接读,需要用宏解释:
WIFEXITED(status):exit或者return正常返回结束的子进程。
WEXITSTATUS(status)、WIFSIGNALED(status)、WTERMSIG(status)、WIFSTOPPED(status)、WSTOPSIG(status)、WIFCONTINUED(status)
options, 默认0,挂起调用进程,直到回收一个子进程。可选参数:WNOHANG、WUNTRACED、WCONTINUED。
如果没有子进程,返回-1,并设置errno为ECHILD。如果被信号中断,返回-1,设置errno为EINTR。
wait相当于waitpid(-1, int *statusp, 0)
4. kill是终止或发送信号给进程。
信号发送产生原因有两种:内核检测到错误,或者进程调用kill。
接收信号处理方式3种:ignore、handler、终止。
信号被阻塞,可被接收,只是不被处理。
发送信号基于进程组。int kill(pid_t pid, int sig), pid为负时,发送给进程组。
unsigned int alarm(unsigned int secs), 发送SIGALRM信号给自己。alarm(0)查看之前的alarm还剩几秒,alarm(n)重新定个闹钟并返回之前的闹钟剩几秒。
5. 前面讲进程对信号有三种处理方式:ignore、handler、终止。这里讲handler默认有:终止、停止直到被SIGCONT信号重启、ignore。
sighandler_t signal(int signum, sighandler_t handler)把处理函数挂到信号上。handler可以为SIG_IGN、SIG_DFL。
6. 编写安全处理handler原则:
尽可能简单、只调用异步信号安全的函数、保存和回复errno、阻塞所有信号、用volatile声明全局变量、用sig_atomic_t声明标志。
7. 因为信号处理因操作系统而异,有一个Signal函数封装,可以跨系统。注意S是大写的。