操作系统带参的信号发送与捕获

带参的信号发送与捕获

  • 可以让不同进程之间发送信号时,带上一些简易数据,完成不同进程之间简单通信,这叫带参数的信号发送

#include <signal.h>
​
int sigaction (int signum, const struct sigaction* act,struct sigaction* oldact);
功能:设置信号的处理方案
signum:信号码
act:信号处理方式
oldact:原信号处理方式,可为NULL
​
struct sigaction {
    void (*sa_handler)(int); // 信号处理函数指针1
    void (*sa_sigaction)(int,siginfo_t*,void*); // 信号处理函数指针2 带附加数据
    sigset_t sa_mask; // 信号掩码
    //在信号函数函数执行过程中,默认屏蔽当前信号,如果想屏蔽其它信号可以向sa_mask中添加
    int sa_flags; // 信号处理标志
    void (*sa_restorer)(void); // 保留,NULL
};
​
sa_flags可为以下值的位或:
    SA_ONESHOT/SA_RESETHAND 执行完一次信号处理后,即对此信号的处理恢复为默认,这也是老版本signal函数的缺省行为。
    SA_NODEFER/SA_NOMASK 在信号处理函数的执行过程中,不屏蔽这个正在被处理的信号。
    SA_NOCLDSTOP 若signum参数取SIGCHLD,则当子进程暂停时,不通知父进程。
    SA_RESTART 系统调用一旦被signum参数所表示的信号中断,会自行重启。
    SA_SIGINFO 使用信号处理函数指针2,通过该函数的第二个参数,提供更多信息。
​
typedef struct siginfo {
    pid_t si_pid;   // 发送信号的PID
    sigval_t si_value; // 信号附加值(需要配合sigqueue函数)
    ...
}siginfo_t;
​
typedef union sigval {
    int sival_int;  整数
    void* sival_ptr;    指针
}sigval_t;
​
int sigqueue (pid_t pid, int sig,const union sigval value);
功能:向pid进程发送sig信号,附加value值(整数或指针)。

在默认情况下,在信号处理函数的执行过程中,会自动屏蔽这个正在被处理的信号,而对于其它信号则不会屏蔽,通过sigaction::sa_mask成员可以人为指定。 在信号处理函数的执行过程中,需要加入进程信号掩码中的信号,并在信号处理函数执行完之后,自动解除对这些信号的屏蔽。

//  进程A
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
​
void sigint1 (int signum)
{
    printf ("收到SIGINT信号!睡眠中...\n");
    sleep (3);
    printf ("睡醒了。\n");
}
​
void sigint2 (int signum, siginfo_t* si, void* pv)
{
    printf ("收到发自%u进程的SIGINT信号!\n", si -> si_pid);
    printf("附加的数据是:%d\n",si->si_value.sival_int);
    //printf("%s\n",si->si_value.sival_ptr);
}
​
int main ()
{
    printf("我是进程%u\n",getpid());
    struct sigaction act = {};
    act.sa_handler = sigint1;
    act.sa_sigaction = sigint2;
    act.sa_flags = SA_SIGINFO;
​
    sigaction (SIGINT, &act, NULL);
    for (;;) pause ();
​
    return 0;
}
//  进程B 给进程A发送附带数据的信号
#include <sys/wait.h>
​
int main (void) 
{
    pid_t pid;
    printf("请输入进程号:");
    scanf("%u",&pid);
​
    sigval_t sv; 
    sv.sival_int = 6666;
    // sv.sival_ptr = "hehehe";
​
    if (sigqueue (pid, SIGINT, sv) == -1) 
    {   
        perror ("sigqueue");
        return -1; 
    }   
    return 0;
}
  • 13
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值