zoukankan      html  css  js  c++  java
  • linux进程篇 (三) 进程间的通信2 信号通信

    2. 信号通信

    用户空间          进程A       <----无法通信---->          进程B
    -----------------|--------------------------------------|--------------
                     |                                      |
    内核空间          |<------------->  信号 <--------------->|    
    
    ----------------------------------------------------------------------
    
    (1) 信号的发送 kill raise alarm
    (2) 信号的接收 pause sleep while
    (3) 信号的处理 signal
    
    
     1) SIGHUP         2) SIGINT         3) SIGQUIT         4) SIGILL         5) SIGTRAP
     6) SIGABRT         7) SIGBUS         8) SIGFPE         9) SIGKILL        10) SIGUSR1
    11) SIGSEGV        12) SIGUSR2        13) SIGPIPE        14) SIGALRM        15) SIGTERM
    16) SIGSTKFLT    17) SIGCHLD        18) SIGCONT        19) SIGSTOP        20) SIGTSTP
    21) SIGTTIN        22) SIGTTOU        23) SIGURG        24) SIGXCPU        25) SIGXFSZ
    26) SIGVTALRM    27) SIGPROF        28) SIGWINCH    29) SIGIO        30) SIGPWR
    31) SIGSYS        34) SIGRTMIN    35) SIGRTMIN+1    36) SIGRTMIN+2    37) SIGRTMIN+3
    38) SIGRTMIN+4    39) SIGRTMIN+5    40) SIGRTMIN+6    41) SIGRTMIN+7    42) SIGRTMIN+8
    43) SIGRTMIN+9    44) SIGRTMIN+10    45) SIGRTMIN+11    46) SIGRTMIN+12    47) SIGRTMIN+13
    48) SIGRTMIN+14    49) SIGRTMIN+15    50) SIGRTMAX-14    51) SIGRTMAX-13    52) SIGRTMAX-12
    53) SIGRTMAX-11    54) SIGRTMAX-10    55) SIGRTMAX-9    56) SIGRTMAX-8    57) SIGRTMAX-7
    58) SIGRTMAX-6    59) SIGRTMAX-5    60) SIGRTMAX-4    61) SIGRTMAX-3    62) SIGRTMAX-2
    63) SIGRTMAX-1    64) SIGRTMAX
    
    发什么信号(64)
    发给谁(pid)

    2.1 信号的发送

    #include <signal.h>
    #include <sys/types.h>
    
    // 发送
    int kill(pid_t pid, int sig);    
    int raise(int sig);    //发信号给自己 == kill(gitpid(),sig)
    #include <unistd.h>
    unsigned alarm(unsigned seconds);
    
    //接收
    while();
    sleep();
    int pause(void); //成功0 失败-1 进程状态为S。 
    
    //处理
    #include <signal.h>
    void (*signal(int sig, void (*func)(int)))(int);
    //or in the equivalent but easier to read typedef'd version:
    typedef void (*sig_t) (int);
    sig_t signal(int sig, sig_t func);
    int kill(pid_t pid, int sig);
    /*pid 
        正数 要接收信号的pid
        0    信号发送到和pid同一个进程组的进程
        -1    信号发送给所有进程表的进程
        
    返回值: 0成功    -1失败
    */
    int raise(int sig);    //发信号给自己 == kill(gitpid(),sig)
    //raise(9) == _exit(),不输出缓存,直接消亡
    #include <unistd.h>
    unsigned alarm(unsigned seconds);
    //和raise一样 只发送信号给自己,延迟一段时间后发送
    //发送闹钟信号的函数    默认处理是终止进程

    2.2 信号的处理

    void (*signal(int sig, void (*func)(int)))(int);
    //or in the equivalent but easier to read typedef'd version:
    typedef void (*sig_t) (int);
    sig_t signal(int sig, sig_t func);
    
    
    //分析void (*signal(int sig, void (*func)(int)))(int);
    void (*func)(int) //函数指针,返回值viod, 1个int参数 -> A
    signal(int sig, A) 所以 signal 返回的就是一个函数指针,
    
    void (*P)(int); //一个带 int参数,返回值为void的函数指针
    //P== signal(int sig, A) 所以 signal 返回的就是一个函数指针,
    typedef void (*sig_t) (int);
    //整个函数有2个地方可以替换
    sig_t signal(int sig, sig_t func)
    typedef void (*sig_t) (int);
    sig_t signal(int sig, sig_t func)
        
    /*
        1,处理什么信号 2,怎样处理这个信号
      
            SIG_IGN 忽视该信号
            SIG_DFL系统默认
            自定义
    */

    例子:

    1.kill 自己写一个杀死进程函数

    #include <stdio.h>
    #include <string.h>
    #include <signal.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <stdlib.h>
    
    int main(int argc, char const *argv[])
    {
        /*kill 并非杀死进程 kill 9 pid 才是杀死一个进程,kill是信号通信的框架。
        * 下面将搭建kill 信号通信的框架
        */
    
        int sig,pid;
        int ret;
    
        if(argc < 3){
            puts("请输入正确的参数 !");
            return -1;
        }
    
        sig = atoi(argv[1]);
        pid = atoi(argv[2]);
        printf("sig = %d, pid = %d
    ", sig,pid);
    
        ret = kill(pid,sig);
        if(ret < 0){
            perror("kill");
            return -2;
        }
        return 0;
    }

    2.signal 信号处理

    #include <stdio.h>
    #include <string.h>
    #include <signal.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/wait.h>    //wait调用相关函数库
    
    #define CHLD 20    //mac CHLD是20,linux 是17
    
    void sig_fun1(int signum){
        int i;
        while(i < 10){
            printf("sig fun ,signum is %d,i =%d
    ",signum,i);
            i++;
            sleep(1);
        }
        return;
    }
    
    void sig_exit(int signum){
        printf("recv sig %d",signum);
        wait(0);
        return;
    }
    
    int main(int argc, char const *argv[])
    {
        pid_t pid;
        pid = fork();
        if(pid > 0){    //子进程
    
            int i;
            signal(10,sig_fun1);
            signal(CHLD,sig_exit);
    
            while(i < 20){
                printf("我是子进程,i = %d
    ",i);
                i++;
                sleep(1);
            }
    
        }else{    //父进程
            sleep(10);
            puts("我是子进程");
            kill(getppid(),10);
            exit(0);
        }
        return 0;
    }
  • 相关阅读:
    WinForm容器内控件批量效验是否同意为空?设置是否仅仅读?设置是否可用等方法分享
    EF的CRUD
    SICP 习题 (1.41)解题总结
    陈光标挽救纽约穷人背后有何玄机?
    poj 1276 Cash Machine(多重背包)
    vue的生命周期
    vue mounted组件的使用
    babel-polyfill的几种使用方式
    可拖拽排序的vue组件
    import、export 和 export default
  • 原文地址:https://www.cnblogs.com/kmist/p/10639911.html
Copyright © 2011-2022 走看看