Linux—信号如何携带消息之高级版

博客介绍了Linux信号携带消息的高级版原理,包括通过绑定sigaction()和使用sigqueue()发送消息。详细说明了sigaction()原函数中act结构需配置的参数,以及siginfo_t结构体用于获取信号信息,还给出了接收端和发送端的demo及运行结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Linux—信号如何携带消息之高级版

携带消息原理:
1、 绑定 sigaction()
2、sigqueue() 发送消息

1、接受、绑定信号sigaction()原函数

#include <signal.h>
   //绑定信号
int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact); 
       参数:
     signum:  要捕捉的信号
       act :   结构体 (要配置的三个重要参数)
     oldact:  NULL(堵塞)
      

act结构需要配置的参数:

struct sigaction {
         void     (*sa_handler)(int);
         void     (*sa_sigaction)(int, siginfo_t *, void *);
        sigset_t   sa_mask;
        int        sa_flags;
        void     (*sa_restorer)(void);
};
参数:
  1、s1a_handler:(不配置)信号处理函数,不接受额外数据,SIG_IGN 为忽略,SIG_DFL 为默认。
  2、sa_sigaction:定义信号处理函数,能够接受额外数据
      a、int         :捕捉到相应的信号值
      b、siginfo_t * :si_value保存了发送过来的信息,同时,在 si_int或者 si_ptr成员中也保存了对应的数据
      c、void *      :信号携带消息的有效值(判断是否为NLL) 
  3、sa_mask      :不配置(默认阻塞关键字的信号)
  4、sa_flags     :SA_SIGINFO 宏接受数据
 

siginfo_t结构体:
获取信号的信息

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 kernel 2.6.32) */
           }

接收端demo:

#include <signal.h>
#include <stdio.h>
         
         
         //void (*sa_sigaction)(int, siginfo_t *, void *);

void  handler(int signum, siginfo_t *data , void * text)
{
        printf("get signal:%d\n",signum);
        if(text != NULL ){
            printf("from_pid:%d\n",data->si_pid);
            printf("data1:%d\n",data->si_int);
            printf("data2:%d\n",data->si_value.sival_int);
        } 
}
int main()
{//int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);
        struct sigaction act;//定义参数2结构体

        printf("pid=%d\n",getpid());
        act.sa_sigaction =handler;//处理消息函数
        act.sa_flags = SA_SIGINFO;//SA_SIGINFO 宏接受数据

        sigaction(SIGUSR1,&act,NULL);

        while(1);

        system("pause");
        return 0;
}

2、sigqueue() 发送消息
sigqueue()函数原型:

int sigqueue(pid_t pid, int sig, const union sigval value); 发消息
   参数:
        pid  :进程pid号
        sig  :捕捉的信号
   value联合体 :发的内容
union sigval {
               int   sival_int;
               void *sival_ptr;
 };

发送端demo:

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

int main(int argc,char **argv)
{
       int pid;
       int signum;
      // int sigqueue(pid_t pid, int sig, const union sigval value);

       printf("pid=%d\n",getpid());
       pid    = atoi(argv[2]); //字符转为整形
       signum = atoi(argv[1]); 

       union sigval value; 
       value.sival_int = 200;

       sigqueue(pid, signum,value);

       system("pause");
       return 0;
}

运行结果:
在这里插入图片描述

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值