网站开发公司可行报告,优秀网站的要素有,佛系wordpress,wang域名 网站SIGCHLD 信号
SIGCHLD 的产生条件
子进程终止时子进程接收到 SIGSTOP 信号停止时子进程处在停止态#xff0c;接受到 SIGCONT 后唤醒时
借助 SIGCHLD 信号回收子进程
子进程结束运行#xff0c;其父进程会收到 SIGCHLD 信号。该信号的默认处理动作是忽略。可以捕捉该信号…SIGCHLD 信号
SIGCHLD 的产生条件
子进程终止时子进程接收到 SIGSTOP 信号停止时子进程处在停止态接受到 SIGCONT 后唤醒时
借助 SIGCHLD 信号回收子进程
子进程结束运行其父进程会收到 SIGCHLD 信号。该信号的默认处理动作是忽略。可以捕捉该信号在捕捉函 数中完成子进程状态的回收。
linux系统根据未决信号集来处理信号多个信号进入未决信号集只处理一次。
#includestdio.h
#includestdlib.h
#includeunistd.h
#includeerrno.h
#includesys/types.h
#includesys/wait.h
#includesignal.h//出错处理函数
void sys_err(char * str)
{perror(str);exit(1);
}void do_sig_child(int signo)
{int status;//传出参数pid_t pid;//进程ID//status子进程退出状态while((pid waitpid(0,status,WNOHANG))0){if(WIFEXITED(status))printf(--------child %d exit %d\n,pid,WEXITSTATUS(status));else if(WIFSIGNALED(status))printf(child %d cancel signal %d\n,pid,WTERMSIG(status));}
}int main(void)
{pid_t pid;int i;//阻塞SIGCHLDfor(i0;i10;i){if((pid fork()) 0){ break;}else if(pid0){sys_err(fork);}}if(pid 0){int n1;while(n--){printf(child ID %d\n,getpid());sleep(1);}return i1;}else if(pid 0 ){//有可能再注册信号过程中子进程死亡所以要先对信号进程阻塞//SIGCHILD阻塞struct sigaction act;act.sa_handler do_sig_child;sigemptyset(act.sa_mask);act.sa_flags 0;sigaction(SIGCHLD,act,NULL);//解除对SIGCHLD的阻塞while(1){printf(Parent ID %d\n,getpid());sleep(1);}}return 0;
} 子进程结束 status 处理方式
pid_t waitpid(pid_t pid,int* status,int options) options WNOHANG 没有子进程结束立即返回 WUNTRACED 如果子进程由于被停止产生的 SIGCHLDwaitpid 则立即返回 WCONTINUED 如果子进程由于被 SIGCONT 唤醒而产生的 SIGCHLDwaitpid 则立即返回获取 status WIFEXITED(status) 子进程正常 exit 终止返回真 WEXITSTATUS(status)返回子进程正常退出值 WIFSIGNALED(status) 子进程被信号终止返回真 WTERMSIG(status) 返回终止子进程的信号值 WIFSTOPPED(status) 子进程被停止返回真 WSTOPSIG(status)返回停止子进程的信号值 WIFCONTINUED(status)
SIGCHLD 注意
子进程继承了父进程的信号屏蔽字和信号处理动作但子进程没有继承未决信号集 spending。注意注册信号捕捉函数的位置。应该在 fork 之前阻塞 SIGCHLD 信号。注册完捕捉函数后解除阻塞。
信号传参
发送信号传参
sigqueue 函数对应 kill 函数但可在向指定进程发送信号的同时携带参数 int sigqueue(pid_t pid,int sig,const union sigvalvalue);成功0失败-1设置
errno union sigval
{ int sival_int;void*sival_ptr;//这个地址给本进程使用
};向指定进程发送指定信号的同时携带数据。但如传地址需注意不同进程之间虚拟地址空间各自独立 将当前进程地址传递给另一进程没有实际意义。
捕捉函数传参
int sigaction (int signum,const struct sigaction*act,struct sigaction*oldact);structsigaction{ void (*sa_handler)(int); void (*sa_sigaction)(int,siginfo_t*,void*); sigset_t sa_mask;int sa_flags; void (*sa_restorer)(void);}; 当注册信号捕捉函数希望获取更多信号相关信息不应使用 sa_handler 而应该使用 sa_sigaction。但此时的 sa_flags 必须指定为 SA_SIGINFO。siginfo_t 是一个成员十分丰富的结构体类型可以携带各种与信号相关的数据。
中断系统调用
系统调用可分为两类慢速系统调用和其他系统调用。
慢速系统调用
可能会使进程永远阻塞的一类。如果在阻塞期间收到一个信号该系统调用就被中断,不再 继续执行(早期)也可以设定系统调用是否重启。如read、write、pause、wait…
其他系统调用
getpid、getppid、fork…
结合 pause 回顾慢速系统调用 慢速系统调用被中断的相关行为实际上就是 pause 的行为 如read
想中断 pause信号不能被屏蔽。信号的处理方式必须是捕捉 (默认、忽略都不可以)中断后返回-1 设置 errno 为 EINTR(表“被信号中断”) 可修改 sa_flags 参数来设置被信号中断后系统调用是否重启。SA_INTERRURT 不重启。 SA_RESTART 重启。
sa_flags 还有很多可选参数适用于不同情况。如捕捉到信号后在执行捕捉函数期间不希望自动阻塞该 信号可将 sa_flags 设置为 SA_NODEFER除非 sa_mask 中包含该信号。