信号

信号

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

信号产生的方式:
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 <stdio.h>
#include <unistd.h>
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 <stdio.h>
#include <unistd.h>
#include <signal.h>
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 <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <pthread.h>//头文件千万别忘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 <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <pthread.h>//头文件千万别忘le
#include <sys/wait.h>

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 <signal.h>
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);

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一、信号及信号来源 信号本质 信号是在软件层次上对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一...
    丶Em1tu0F阅读 1,470评论 0 1
  • 进程之间可以通过信号传递信息,信号是一种软中断机制,通过信号用来通知进程发生了异步事件。进程之间可以互相通过系统调...
    lintong阅读 419评论 0 2
  • 使用场景:1、为了并发,中断处理其它事件,1、进程间通信1、中断中止(注意不是终止)当前正在执行的程序,转而执行其...
    奥斯特洛司机阅读 714评论 0 0
  • 上海 地理课本上的描述气候是亚热带季风气候 ,来到上海 不凉不热 ,感觉好的,上海的老建筑 老品牌 凤凰黄金完美...
    嗨皮呦阅读 79评论 0 1
  • 现在分享星期六下午督导的另一咨询案例,这个案例由我来暴露,该例主要为家长咨询怎样改变自己,影响孩子,促进...
    田愿阅读 283评论 0 0