Linux signals(三) 使用sigval进行进程间通信 实例代码

时间:2022-05-11 00:09:41
siginfo_t {
               int      si_signo;    /* Signal number */
               int      si_errno;    /* An errno value */
               int      si_code;     /* Signal code */
               int      si_trapno;   /* Trap number that caused hardware-generated signal (unused on most architectures) */
               pid_t    si_pid;      /* Sending process ID */
               uid_t    si_uid;      /* Real user ID of sending process */
               int      si_status;   /* Exit value or signal */
               clock_t  si_utime;    /* User time consumed */
               clock_t  si_stime;    /* System time consumed */
               sigval_t si_value;    /* Signal value */
               int      si_int;      /* POSIX.1b signal */
               void    *si_ptr;      /* POSIX.1b signal */
               int      si_overrun;  /* Timer overrun count; POSIX.1b timers */
               int      si_timerid;  /* Timer ID; POSIX.1b timers */
               void    *si_addr;     /* Memory location which caused fault */
               long     si_band;     /* Band event (was int in glibc 2.3.2 and earlier) */
               int      si_fd;       /* File descriptor */
               short    si_addr_lsb; /* Least significant bit of address (since Linux 2.6.32) */
           }
union sigval {
    int sival_int;
    void *sival_ptr;
};

发送进程

#include<stdio.h>
#include<signal.h>
#include<unistd.h>
#include<string.h>

int main(int argc,char *argv[])
{
    if(argc!=2)
    {
        printf("arguments error!");
        exit(0);
    }

    pid_t pid=atoi(argv[1]);//将进程号转化为整数
    union sigval v;
    v.sival_int=100;
    //这儿只是利用SIGINT来发送数据,
    //任何信号都行,只需要发送端与接收端规定一致即可
    sigqueue(pid,SIGINT,v);
    return 0;
}

接收进程

#include<stdio.h>
#include<unistd.h>
#include<signal.h>
#include<string.h>
//#include<sys/siginfo.h>

void handler(int,siginfo_t *,void *);

int main(void)
{
    struct sigaction act;
    act.sa_sigaction=handler;
    sigemptyset(&act.sa_mask);
    act.sa_flags=SA_SIGINFO;
    if(sigaction(SIGINT,&act,NULL)<0)
    {
        printf("error");
        exit(0);
    }
    for(;;)
        pause();
    return 0;
}

void handler(int sig,siginfo_t * info,void *ctx)
{
    printf("recv a sid=%d data=%d data=%d\n",sig,info->si_value.sival_int,info->si_int);
}

运行结果:

//首先运行接收进程
[root@izwz9j36enzsqqima735r4z cprograms]# ./sigrecv 
//然后打开另一个终端连接
//查看接收进程的进程号
[root@izwz9j36enzsqqima735r4z cprograms]# ps aux
[root@izwz9j36enzsqqima735r4z cprograms]# ./sigsend 12752
//在一开始的终端内运行的接收进程接收到消息
recv a sid=2 data=100 data=100
//自己给自己发送,当然也能接收到
^Crecv a sid=2 data=100 data=100
//终止进程
^Z
[2]+  已停止               ./sigrecv