进程间通信IPC-信号

1,signal-ANSI C信号处理

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

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

~$ kill -l
 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

每个信号的含义和产生可以通过 查看linux编程手册:man 7 signal 

handler参数有3种:

a)SIG_IGN,表示忽略该信号

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

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

#include <signal.h>
void my_signal_handler(int sig)
{
    //do something
}

int main(int argc, char* argv[])
{
    singal(SIGUSR1, my_signal_handler); //注册信号捕捉函数
    //do something
    return 0;
}

2,sigaction-信号处理system call

#include <signal.h>
int sigactoin(int signum, const struct sigaction *act, struct sigaction *oldact);//注册信号处理
int sigemptyset(sigset_t *set);//清空全部信号sigset_t,用于sa_mask
int sigfillset(sigset_t *set);//填充全部信号sigset_t,用于sa_mask
int sigaddset(sigset_t *set, int signum);//增加某信号到sigset_t,用于sa_mask
int sigdelset(sigset_t *set, int signum);//从sigset_t中删除某信号,用于sa_mask
int sigismember(const sigset_t *set, int signum);//是否存在
struct sigaction {
    void     (*sa_handler)(int); //默认信号处理函数
    void     (*sa_sigaction)(int, siginfo_t *, void *); //sa_flag设置为SA_SIGINFO时常用的信号处理函数
    sigset_t   sa_mask; //屏蔽信号集合
    int        sa_flags; //定义的行为
    void     (*sa_restorer)(void); //已弃用
};

#include <stdlib.h>
#include <signal.h>

void my_signal_handler(int sig)
{
    //do something
}

int addmysignal(int signum, void (* my_signal_handler)(int))
{
    struct sigaction sa;
    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = my_signal_handler;
    sa.sa_flags |= SA_RESTART; //自动重启该信号signum捕捉
    sigfillset(&sa.sa_mask); //屏蔽(阻塞)所有其他信号,当捕捉到signum并执行信号处理函数时。
    return sigaction(signum, &sa, NULL);//这里暂时忽略oldact;
}

int main(int argc, char* argv[])
{
    //注册信号捕捉函数
    if (addmysignal(SIGUSR1, my_signal_handler) < 0)
    {
        exit(EXIT_FAILURE);
    } 
    //do something
    return 0;
}

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


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

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

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

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

示例代码略。


你可能感兴趣的:(信号,Signal,进程间通信)