zoukankan      html  css  js  c++  java
  • Linux的SIGUSR1和SIGUSR2信号

    SIGUSR1 用户自定义信号 默认处理:进程终止
    SIGUSR2 用户自定义信号 默认处理:进程终止

     当一个进程调用fork时,因为子进程在开始时复制父进程的存储映像,信号捕捉函数的地址在子进程中是有意义的,所以子进程继承父进程的信号处理方式。
            但是当子进程调用exec后,因为exec运行新的程序后会覆盖从父进程继承来的存储映像,那么信号捕捉函数在新程序中已无意义,所以exec会将原先设置为要捕捉的信号都更改为默认动作。

    C++父子进程使用SIGUSR1和SIGUSR2进行通信

    #include <stdio.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <unistd.h>
    #include <sys/wait.h>
    
    void handler(int signo)
    {
        switch(signo) {
        case SIGUSR1: //处理信号 SIGUSR1
            printf("Parent : catch SIGUSR1
    ");
    		break;
        case SIGUSR2: //处理信号 SIGUSR2
            printf("Child : catch SIGUSR2
    ");
    		break;
        default:      //本例不支持
            printf("Should not be here
    ");
            break;
        }
    }
    
    int main(void)
    {
        pid_t ppid, cpid;
        //为两个信号设置信号处理函数
        if(signal(SIGUSR1, handler) == SIG_ERR) 
    	{ //设置出错
            perror("Can't set handler for SIGUSR1
    ");
            exit(1);
        }
    
        if(signal(SIGUSR2, handler) == SIG_ERR) 
    	{ //设置出错
            perror("Can't set handler for SIGUSR2
    ");
            exit(1);
        }
    
        ppid = getpid();//得到父进程ID
    
        if((cpid = fork()) < 0) 
    	{
            perror("fail to fork
    ");
            exit(1);
        } 
    	else if(cpid == 0) 
    	{
    		// 子进程内向父进程发送信号SIGUSER1
            if(kill(ppid, SIGUSR1) == -1) 
    		{
                perror("fail to send signal
    ");
                exit(1);
            }
    
            while(1);//死循环,等待父进程的信号
        } 
    	else 
    	{
            sleep(1);//休眠,保证子进程先运行,并且发送SIGUSR1信号
    		// 父进程向自己发送SIGUSER2信号
            if(kill(cpid, SIGUSR2) == -1)
    		{
                perror("fail to send signal
    ");
                exit(1);
            }
    		
    		// 必须sleep一下,否则子进程捕获不到SIGUSER2信号
    		sleep(1);
    
            printf("will kill child
    ");//输出提示
            if(kill(cpid, SIGKILL) == -1) 
    		{ //发送SIGKILL信号,杀死子进程
                perror("fail to send signal
    ");
                exit(1);
            }
    
            if(wait(NULL) ==-1) 
    		{ //回收子进程状态,避免僵尸进程
                perror("fail to wait
    ");
                exit(1);
            }
    		printf("child has been killed.
    ");
        }
        return;
    }
    

      

    捕捉SIGUSR1和SIGUSR2的简单程序

    #include <stdio.h>
    #include <signal.h>
    #include <unistd.h>
    
    static void sig_usr(int);
    int main(void)
    {
            if(signal(SIGUSR1, sig_usr) == SIG_ERR)
                printf("can not catch SIGUSR1
    ");
            if(signal(SIGUSR2, sig_usr) == SIG_ERR)
                printf("can not catch SIGUSR2
    ");
            for(;;)
                    pause();
    }
    
    static void sig_usr(int signo)
    {
            if(signo == SIGUSR1)
                printf("received SIGUSR1
    ");
            else if(signo == SIGUSR2)
                printf("received SIGUSR2
    ");
            else
                printf("received signal %d
    ", signo);
    }
    运行结果:
    [chinsung@thinkpad apue]$ ./a.out &
    [1] 2581
    [chinsung@thinkpad apue]$ kill -USR1 2581
    received SIGUSR1
    [chinsung@thinkpad apue]$ kill -USR2 2581
    received SIGUSR2
    [chinsung@thinkpad apue]$ kill 2581
    [1]+ Terminated              ./a.out
    

      

  • 相关阅读:
    Qt 学习之路:元素布局
    Qt 学习之路 2(80):定位器
    Qt 学习之路 2(79):QML 组件
    Qt 学习之路:QML 组件
    Qt 学习之路:QML 基本元素
    qt 学习之路 :QML 语法
    Qt 学习之路:QML 和 QtQuick 2
    Qt 学习之路:线程总结
    Qt 学习之路:线程和 QObject
    五步教你实现使用Nginx+uWSGI+Django方法部署Django程序
  • 原文地址:https://www.cnblogs.com/kex1n/p/8296332.html
Copyright © 2011-2022 走看看