Linux进程通信——信号进阶(信号如何携带消息)

Linux进程通信——信号携带消息

  • 信号和信号携带消息异同点
  • 信号接收和发送函数
  • 接收函数
  • 接收端

信号和信号携带消息异同点

信号相关内容Linux——信号入门

信号处理函数的注册:
入门版:函数signal
高级版:函数sigaction

信号处理发送函数:
入门版:kill
高级版:sigqueue

入门版本的信号注重于动作,而高级版本注重于内容
例如有人敲门,把敲门当作一个信号。入门版只能听见敲门声,而高级版则伴随着敲门和信息。敲门的人可以告诉你他是谁,找你有什么事。

信号接收和发送函数

#include 
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
//signum为信号类型
// const struct sigaction *act为结构体,配置内容
//struct sigaction *oldact 一般当作备份使用
struct sigaction {
   void       (*sa_handler)(int); //信号处理程序,不接受额外数据。这个参数被调用,则和入门版没有区别,只能执行中断函数里的内容,而无法接收数据
   void       (*sa_sigaction)(int, siginfo_t *, void *); //信号处理程序,能够接受额外数据和sigqueue配合使用
   sigset_t   sa_mask;//阻塞关键字的信号集,可以再调用捕捉函数之前,把信号添加到信号阻塞字,信号捕捉函数返回之前恢复为原先的值。一般默认为阻塞,当接收一个信号时,对其它信号不进行处理
   int        sa_flags;//影响信号的行为SA_SIGINFO表示能够接受数据
 };
//回调函数句柄sa_handler、sa_sigaction只能任选其一
//若要接收消息,只需要配第二个和第四个参数
//该函数需要配合sigqueue函数使用
void (*sa_sigaction)(int, siginfo_t *, void *); //信号处理程序,能够接受额外数据和sigqueue配合使用
该函数 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 */
               int      si_band;     /* Band event */
               int      si_fd;       /* File descriptor */
}
可以看到高级版信号可以接收很多消息

接收函数

#include 
#include 
#include 
#include 

void handler(int signum,siginfo_t *info,void *content)
   {
          printf("signum:%d\n",signum);
          printf("content:%d\n",info->si_int);
   }

int main()
{
   struct sigaction act;
   act.sa_sigaction = handler;
   act.sa_flags     = SA_SIGINFO;
   sigaction(SIGUSR1,&act,NULL);
   printf("%d\n",getpid());
   while(1);
   return 0;
}

接收端

#include 
#include 
#include 
int main(int argc,char **argv)
{
    int pid;
    int signum;
    pid    = atoi(argv[1]);
    signum = atoi(argv[2]);
    union sigval value;
    value.sival_int = 16;
    sigqueue(pid,signum,value);
    printf("done!\n");
}

Linux进程通信——信号进阶(信号如何携带消息)_第1张图片
发送成功!
注意:发送字符串只能在 共享内存或者 同一进程下 才可以发送!

你可能感兴趣的:(linux,运维,服务器)