信号
简单信息,类似于中断 ,软中断,异步处理。
信号产生的方式:
1、按键产生的信号:Ctrl+c 中断 ctrl +\ Ctrl+z 切换到后台运行
2、系统调用: kill alarm
3、命令:kill
4、硬件:总线错误 段错误
5、软件:sleep
递达:成功发送信号
未决:
信号:
1、默认的处理方式
2、忽略
3、捕捉(自定义处理)
信号四个要素:
信号名字 编号 行为 默认的处理方式
相关系统调用
alarm 定时器 每个进程只有一个定时器
alarm(5)--3s--alarm(10)---5s---alarm(0)(结束定时器)
练习:1s 中打印多少行。
#include
#include
int main(){
alarm(1);
int i = 1;
while(i++){
printf("hello:%d\n",i);
}
}
kill
1、kill命令结束进程
了解进程组概念,(默认进程组ID同父进程)
kill -9 进程ID (-9表示信号为SIGKILL的编号 ) :杀死进程
kill -9 -进程ID :杀死进程组。
2、kill函数结束进程。
#include
#include
#include
void exit(int);
void sys_err(const char *str)
{
perror(str);
exit(1);
}
int main(){
pid_t pid_ret = fork();
if(-1 == pid_ret)sys_err("fork Err");
if(0 == pid_ret){
printf("child:%d:%d:%d\n",getpid(),getppid(),getpgid(0));
sleep(2);
}
if(pid_ret>0){
printf("parent:%d:%d:%d\n",getpid(),getppid(),getpgid(0));
printf("child pid :%d\n",pid_ret);
if(kill(pid_ret,SIGKILL)==0){printf("kill success");};
}
}
捕捉
signal :注册信号处理捕捉函数(类似于 备案)
#include
#include
#include
#include //头文件千万别忘le
void exit(int);
void sys_err(const char *str)
{
perror(str);
exit(1);
}
void func(int a){
printf("***signal:%d\n***",a);
return;
}
int main(){
signal(SIGINT,func);
//struct sigaction act;
//act.sa_handler = func;
//sigemptyset(&(act.sa_mask));
//act.sa_flags = 0;
//sigaction(2, &act,NULL);
while(1){
printf("hello\n");
sleep(5);}
return 0;
}
利用捕捉信号回收子进程
#include
#include
#include
#include //头文件千万别忘le
#include
void exit(int);
void sys_err(const char *str)
{
perror(str);
exit(1);
}
void func(int a){
printf("signo=%d:waitpid=%d\n",a,wait(NULL));
return;
}
int main(){
int i=0;
for(;i<5;i++){
pid_t pid_ret = fork();
if(pid_ret == 0)
{
break;
}
}
if(5 == i){
struct sigaction act;
act.sa_handler = func;
sigemptyset(&(act.sa_mask));
act.sa_flags = 0;
sigaction(SIGCHLD, &act,NULL);
printf("parent\n");
while(1);
}
else{
printf("child:%d\n",getpid());
}
return 0;
}
2020/3/10 补充
发送信号的函数
1、kill
2、raise 自己给自己发
3、abort 自己给自己发+终止信号 abort()无参数
4、alarm 有且只有一个
发送的信号就是 SIGALRM 终止进程
返回值:
成功:如果调用此alarm()前,进程中已经设置了闹钟时间,
则返回上一个闹钟时间的剩余时间,否则返回0。
time 可以统计当前进程运行的时间
alarm(0)取消闹钟
5、setitimer 定时器 精度微妙 可以实现周期定时(了解)
信号捕捉
1、signal
//回调函数
void sig_fun(int num)
{
;
}
signal(SIGINT,sig_fun);
//注意:
注册SIGINT信号的捕捉函数,内核会帮助我们调用sig_fun函数
2、sigaction函数 ----待补充
#include
int sigaction(int signum, const struct sigaction *act,
struct sigaction *oldact);
SIG_DFL:默认信号处理程序
SIG_IGN:忽略信号的处理程序
signal(SIGTERM,SIG_IGN);//忽略信号kill PID
signal(SIGTSTP,SIG_DFL);//ctrl + z 执行默认操作
SIGCHLD
SIGCHLD信号,在子进程结束的时候,默认会给父进程发送一个SIGCHLD信号
发送信号
signal(SIGCHLD,sig_fun);