• Linux 进程间通信---信号


    一、信号基本概念

    1.是什么?

    (1)比如红绿灯,进程就像车流,当这个车道的红灯亮起来,这个车道的车流就被停下来,(这个时候,在车里的你,可以看下手机或者抽根烟),红绿灯属于这个交通系统,当某个人横穿马路时,这个车道的车流也停了下来,属于外部信号。
    (2)当一个车道里有救护车响着警笛穿过来,这时候其他车道停下来,等带救护车通过,相当于,一个进程发送一个信号给另外一个进程。
    (3)一个信号的产生叫生成,接收到一个信号的行为叫捕捉;

    2.信号的生命周期

    (1)信号的三个阶段:①产生信号;②发送信号给进程;③信号的处理和注销;
    (2)信号处理的过程;
    1)触发信号(可以是系统内部:定时器、硬件异常、也可能是系统外部)
    2)注册操作,进入用户空间,找到目标进程的pid将信号值加入到该进程的未处理的信号集合中;
    3)信号注销 ,在信号集合中的信号,是进程将要处理的,当CPU处理完其他事情,处理该信号时,先从未处理信号集合中注销该信号,然后立即执行信号处理函数;

    3. 信号处理机制

    (1)忽略信号 函数信号处理函数指针宏:SIG_IGN

    typedef void (*sighandler_t) (int);
    sighandler_t signal(int signum,sighandler_t handler);
    //功能:注册信号处理函数
    //返回值:成功返回信号原来处理方式对应的函数指针值,失败返函数指针:SIG_EER;
    //参数:
    //signum   捕捉的信号名称
    //handler   信号处理函数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    (2)默认操作,没有什么影响,默认怎么执行就怎么执行。 SIG_DFL

    if(signal(SIGINT,SIG_DFL)==SIG_EER)
    {
    	perror("Fail to signal");
    	return ;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5

    (3)捕捉信号
    定义并注册信号处理函数,当信号发生时,执行相应的处理函数。

    if(siganl(SIGINT,func)==SIG_ERR)//func  信号处理函数的函数名
    {
    	perror("Fail to signal");
    	return -1;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    示例:子进程结束会给父进程发送 SIGCHLD信号,父进程收到这个信号,则调用waitpid(-1,NULL,WNOHANG)回收子进程。

    #include
    #include
    #include
    #include
    #include
    void func(int signal)
    {
    	waitpid(-1,NULL,WNOHANG);
    	printf("child\n");
    }
    
    int main(int argc, const char *argv[])
    {
    	pid_t pid;
    
    	if(signal(SIGCHLD,func)==SIG_ERR)
    	{
    		perror("Fail to signal");
    		return -1;
    	}
    	pid=fork();
    	if(pid<0)
    	{
    		perror("Fail to pid");
    		return -1;
    	}
    	else if(pid==0)
    	{
    		sleep(5);
    		exit(EXIT_SUCCESS);
    	}
    	else
    	{
    		while(1)
    		{
    			printf("father process is running...\n");
    			sleep(1);
    		}
    	}
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    4.信号发送函数

    (1)int kill(pid_t pid,int sigum);//给指定pid 发送信号

    int kill(pid_t pid,int sigum);
    //功能:给指定pid 发送信号
    //返回值:成功返回0 失败返回-1
    //参数: 
    //pid  进程pid
    //sigum  信号
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    (2)int raise(int signum);//给自己发信号

    int raise(int signum);
    //功能:给自己发送信号
    //返回值:成功返回0 失败返回-1
    //参数: 
    //signum 信号
    
    • 1
    • 2
    • 3
    • 4
    • 5

    (3)int alarm(unsigned int seconds);//经过seconds 秒把SIGALRM信号发送给当前进程。

    在SIGALRM信号处理函数中再写入alarm()函数,可实现套娃,每隔seconds 秒发送SIGALRM信号。

    unsigned int alarm(unsigned int seconds);
    //返回值:成功返回0 失败返回-1
    //参数:
    //seconds  秒
    
    • 1
    • 2
    • 3
    • 4
  • 相关阅读:
    SpringBoot项目--电脑商城【获取省市区列表】
    游戏出海,全球化运营
    2023年浙大MEM考前80天上岸经验分享
    计算机保研-上岸华中科技大学(武汉光电国家研究中心)
    手写数组方法之用于遍历的方法
    Unity3D 关于过大的UI帧动画如何处理详解
    LeetCode 2000. Reverse Prefix of Word
    【C++】C++入门
    学会这个样生成性能测试报告,拿下20k轻轻松松
    数据结构逻辑结构物理结构
  • 原文地址:https://blog.csdn.net/jun8086/article/details/127784192