可靠信号和不可靠信号的测试

来源:互联网 发布:淘宝卖家感谢信范文 编辑:程序博客网 时间:2024/04/30 05:36
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <signal.h>/*     1. 创建子进程和父进程    2. 注册 SIGINT 非实时信号 SIGRTMIN 实时信号,添加到进程阻塞中    3. 注册用户自定义信号 SIGQUIT    4. 子进程发送3次非实时信号,发3次实时信号    5. 子进程发送SIGQUIT解除信号阻塞    6. 观察实时信号和非实时信号的表现与区别 */// int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);  -----> 设置信号阻塞或非阻塞//        int sigaction(int signum, const struct sigaction *act,    -----> 信号安装函数//                     struct sigaction *oldact);void handle(int signum, siginfo_t *info, void *p);int main(void){    pid_t fpid, pid;    sigset_t mset;          // 信号集    struct sigaction act;   // act结构体中含信号处理函数    act.sa_sigaction = handle;      // 信号处理函数    act.sa_flags = SA_SIGINFO;      // 标志位为SA_SIGINFO时,sigaction函数才能接收sigqueue发送的信号    // 安装三个信号,一个实时(SIGRTMIN),一个非实时(SIGINT),一个通过键盘发送信号测试程序(SIGQUIT)    sigaction(SIGINT, &act, NULL);    sigaction(SIGRTMIN, &act, NULL);    sigaction(SIGQUIT, &act, NULL);    // 设置实时和非实时信号阻塞    sigemptyset(&mset);    sigaddset(&mset, SIGINT);    sigaddset(&mset, SIGRTMIN);    sigprocmask(SIG_BLOCK, &mset, NULL);    fpid = fork();    if (fpid == -1) {        perror("MSG");        exit(0);    }// int sigqueue(pid_t pid, int sig, const union sigval value);    if (fpid == 0) {        union sigval value;        int i = 0, ret = 0;        pid = getppid();        for (i = 1; i < 4; i++) {            value.sival_int = i;            // 给父进程发送信号, 3个非实时信号            ret = sigqueue(pid, SIGINT, value);            if (ret != 0) {                printf("发送非实时信号失败\n");            }            printf("发送非实时信号成功\n");        }        for (i = 1; i < 4; i++) {            value.sival_int = i;            // 给父进程发送信号,3个非实时信号            ret = sigqueue(pid, SIGRTMIN, value);            if (ret != 0) {                printf("发送实时信号失败\n");            }            printf("发送实时信号成功\n");        }        value.sival_int = 1942;        //sigqueue(pid, SIGQUIT, value);    }    while (1) {        pause();    }    return 0;}// 信号处理函数,当被阻塞时,不会调用此函数void handle(int signum, siginfo_t *info, void *p){    int num = 0;    num = info->si_value.sival_int;    if (signum == SIGINT) {        printf("recv signal %d\n", signum);        printf("recv value %d\n", num);    }    if (signum == SIGRTMIN) {        printf("recv signal %d\n", signum);        printf("recv value %d\n", num);    }    // 通过键盘发送SIGQUIT信号时,会执行下面的代码,作用:    // 解除阻塞信号集,解除后,进程会执行上面两个if分支,非实时信号会丢失,三个丢失了两个    // 实时信号没有丢失    if (signum == SIGQUIT) {        sigset_t uset;        sigemptyset(&uset);        sigaddset(&uset, SIGINT);        sigaddset(&uset, SIGRTMIN);        sigprocmask(SIG_UNBLOCK, &uset, NULL);        printf("SIGINT and SIGRTMIN 已经解除阻塞\n");    }}/*    运行结果:    [root@Mysql-dev signal]# ./sigaction     发送非实时信号成功    发送非实时信号成功    发送非实时信号成功    发送实时信号成功    发送实时信号成功    发送实时信号成功    ^\SIGINT and SIGRTMIN 已经解除阻塞    recv signal 2    recv value 1    recv signal 34    recv value 1    recv signal 34    recv value 2    recv signal 34    recv value 3    SIGINT and SIGRTMIN 已经解除阻塞    可以看到发送的时候,都是三个,解除阻塞接受的时候,只有实时信号没有被丢失,非实时信号丢失了两个*/
0 0
原创粉丝点击