信号
信号是软件中断的模拟,可以在任何时候发给进程,如果进程处于未执行状态,该信号就由内核保存,直到进程恢复执行再传递给它。
SIGKILL和SEGSTOP是应用程序无法捕捉和忽略的。
几个常用的快捷键和信号:
ctrl + C
—— SIGINT 中断信号
ctrl + \
—— SIGQUIT 退出信号
ctrl + Z
—— SIGTSTP 进程挂起
functions about signals:
function | introduction |
---|---|
int kill(pid_t pid, int sig) | send signal to a process |
int raise(int sig) | send a signal to the caller |
unsigned int alarm(unsigned int seconds) | set an alarm clock for delivery of a signal |
int pause(void) | wait for signal |
typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler); | ANSI C signal handling |
int sigemptyset(sigset_t *set) | initializes the signal set given by set to empty, with all signals excluded from the set. |
int sigfillset(sigset_t *set) | initializes set to full, including all signals |
int sigaddset(sigset_t *set, int signum) | add respectively signal signum from set |
int sigdelset(sigset_t *set, int signum) | delete respectively signal signum from set |
int sigismember(const sigset_t *set, int signum) | tests whether signum is a member of set |
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset) | examine and change blocked signals |
下面是子进程给自己发送SIGSTOP信号,用于暂停进程。父进程中waitpid(pid,0,WNOHANG)
用于子进程没有退出立即返回(return immediately if no child has exited.)。
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
int main(){
pid_t pid = fork();
if(pid == 0){ // child
printf("child id is %d\n",getpid());
raise(SIGSTOP);
}
else if(pid > 0){ // father
printf("father pid is %d\n",getpid());
if(waitpid(pid,0,WNOHANG) == 0){
int ret = kill(pid,SIGKILL);
if(ret < 0) perror("ending child failed ");
else printf("father process end child process.\n");
}
}
else {
perror("fork ");
exit(1);
}
return 0;
}
/*
father pid is 6284
father process end child process.
*/
alarm用于设置多少秒后发出SIGALAR信号,时间片函数控制事件发生的时间点。
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
void handler(int sig){
printf("hello world\n");
}
int main(){
int i;
alarm(3);
signal(SIGALRM,handler);
for(i=1;i<=6;i++){
printf("times is %d\n",i);
sleep(1);
}
return 0;
}
/*
times is 1
times is 2
times is 3
hello world
times is 4
times is 5
times is 6
*/
信号的阻塞:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
void handler(){
printf("signal SIGINT has been blocked for 5 seconds, now it works.\n");
}
int main(){
signal(SIGINT,handler);
int i;
sigset_t set;
if(sigemptyset(&set) == -1){
perror("sigemptyset ");
}
if(sigaddset(&set,SIGINT) == -1){
perror("sigaddset ");
}
if(sigprocmask(SIG_BLOCK,&set,NULL) == -1){ /* make set blocked */
perror("sigpromask ");
}
raise(SIGINT);
for(i=0;i<5