信号

信号

简单信息,类似于中断 ,软中断,异步处理。

信号产生的方式:
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);

你可能感兴趣的:(信号)