zoukankan      html  css  js  c++  java
  • 进程间通信IPC-信号

    1,signal-ANSI C信号处理

    1 #include <signal.h>
    2 typedef void (*sighandler_t)(int);
    3 sighandler_t signal(int signum, sighandler_t handler);

     

    signal是ANSI C实现的信号处理函数,signum表示信号ID,常用的信号有:

     1 ~$ kill -l
     2  1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
     3  6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
     4 11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
     5 16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
     6 21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
     7 26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
     8 31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
     9 38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
    10 43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
    11 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
    12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
    13 58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
    14 63) SIGRTMAX-1  64) SIGRTMAX
    每个信号的含义和产生可以通过 查看linux编程手册:man 7 signal 

    handler参数有3种:

    a)SIG_IGN,表示忽略该信号

    b)SIG_DFL,表示捕捉到某信号采用系统默认的处理方式,查看signal(7)

    c)自定义信号处理函数,如下:

     1 #include <signal.h>
     2 void my_signal_handler(int sig)
     3 {
     4     //do something
     5 }
     6 
     7 int main(int argc, char* argv[])
     8 {
     9     singal(SIGUSR1, my_signal_handler); //注册信号捕捉函数
    10     //do something
    11     return 0;
    12 }

    2,sigaction-信号处理system call

     1 #include <signal.h>
     2 int sigactoin(int signum, const struct sigaction *act, struct sigaction *oldact);//注册信号处理
     3 int sigemptyset(sigset_t *set);//清空全部信号sigset_t,用于sa_mask
     4 int sigfillset(sigset_t *set);//填充全部信号sigset_t,用于sa_mask
     5 int sigaddset(sigset_t *set, int signum);//增加某信号到sigset_t,用于sa_mask
     6 int sigdelset(sigset_t *set, int signum);//从sigset_t中删除某信号,用于sa_mask
     7 int sigismember(const sigset_t *set, int signum);//是否存在
     8 struct sigaction {
     9     void     (*sa_handler)(int); //默认信号处理函数
    10     void     (*sa_sigaction)(int, siginfo_t *, void *); //sa_flag设置为SA_SIGINFO时常用的信号处理函数
    11     sigset_t   sa_mask; //屏蔽信号集合
    12     int        sa_flags; //定义的行为
    13     void     (*sa_restorer)(void); //已弃用
    14 };
    15  
    16 
    17 #include <stdlib.h>
    18 #include <signal.h>
    19 
    20 void my_signal_handler(int sig)
    21 {
    22     //do something
    23 }
    24 
    25 int addmysignal(int signum, void (* my_signal_handler)(int))
    26 {
    27     struct sigaction sa;
    28     memset(&sa, 0, sizeof(sa));
    29     sa.sa_handler = my_signal_handler;
    30     sa.sa_flags |= SA_RESTART; //自动重启该信号signum捕捉
    31     sigfillset(&sa.sa_mask); //屏蔽(阻塞)所有其他信号,当捕捉到signum并执行信号处理函数时。
    32     return sigaction(signum, &sa, NULL);//这里暂时忽略oldact;
    33 }
    34 
    35 int main(int argc, char* argv[])
    36 {
    37     //注册信号捕捉函数
    38     if (addmysignal(SIGUSR1, my_signal_handler) < 0)
    39     {
    40         exit(EXIT_FAILURE);
    41     } 
    42     //do something
    43     return 0;
    44 }

    sa_flags参数可通过查看linux编程手册进一步了解:man sigaction

     从上述两种信号处理的使用方式来看,好像没有进程间通信什么事。那进程间是如何利用signal来进行通信的呢?

    1 #include <sys/types.h>
    2 #include <signal.h>
    3 int kill(pid_t pid, int sig);

    通过系统调用kill向指定进程发送指定信号,pid进程收到sig后,执行信号处理函数,这就实现了进程间通信。

    同时我们在使用信号进程通信的同时,还可以借助管道,实现两进程间的数据交互。

    示例代码略。

  • 相关阅读:
    LocalDate、LocalTime、LocalDateTime示例
    Instant时间戳示例
    Mybatis面试题
    SpringMVC面试题
    Spring面试题
    redis面试题
    计算机网络面试题
    java集合面试题
    java基础面试题
    MySQL面试题汇总
  • 原文地址:https://www.cnblogs.com/borey/p/5625955.html
Copyright © 2011-2022 走看看