zoukankan      html  css  js  c++  java
  • Linux 信号详解六(可靠信号与不可靠信号)

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <errno.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <signal.h>
    
    void catch_signal(int signo, siginfo_t *info, void *p)
    {
        switch (signo)
        {
        case SIGINT:
            printf("accept SIGINT!  recv data=%d
    ",info->si_value.sival_int);
            break;
        case 34:
            //SIGRTMIN似乎不是一个确定的int类型
            printf("accept SIGRTMIN! recv data=%d
    ",info->si_value.sival_int);
            break;
        case SIGUSR1:
            printf("accept SIGUSR1!
    ");
            //取消信号阻塞
            sigset_t uset;
            sigemptyset(&uset);
            sigaddset(&uset, SIGINT);
            sigaddset(&uset, SIGRTMIN);
            sigprocmask(SIG_UNBLOCK, &uset, NULL);
            printf("阻塞解除了!
    ");
            break;
        }
    }
    
    int main(int arg, char *args[])
    {
        pid_t pid = 0;
        struct sigaction act;
        act.sa_sigaction = catch_signal;
        sigemptyset(&act.sa_mask);
        act.sa_flags = SA_SIGINFO;
        //注册SIGINT信号
        if (sigaction(SIGINT, &act, NULL) != 0)
        {
            printf("sigaction SIGINT failed !
    ");
            return -1;
        }
        //注册SIGTMIN信号
        if (sigaction(SIGRTMIN, &act, NULL) != 0)
        {
            printf("sigaction SIGINT failed !
    ");
            return -1;
        }
        //注册SIGUSR1信号
        if (sigaction(SIGUSR1, &act, NULL) != 0)
        {
            printf("sigaction SIGINT failed !
    ");
            return -1;
        }
        //阻塞SIGINT信号和SIGTMIN信号
        sigset_t bset;
        sigemptyset(&bset);
        sigaddset(&bset, SIGINT);
        sigaddset(&bset, SIGRTMIN);
        //更新进程屏蔽信号状态字
        if (sigprocmask(SIG_BLOCK, &bset, NULL) != 0)
        {
            printf("sigprocmask() failed !
    ");
            return -1;
        }
        pid = fork();
        if (pid == -1)
        {
            printf("fork() failed ! error message:%s
    ", strerror(errno));
            return -1;
        }
        if (pid == 0)
        {
            int i = 0, ret = 0;
            union sigval v1;
            union sigval v2;
            for (i = 0; i < 3; i++)
            {
                v1.sival_int = 201 + i;
                ret = sigqueue(getppid(), SIGINT, v1);
                if (ret != 0)
                {
                    printf("发送不可靠信号SIGINT失败! error message:%s
    ", strerror(errno));
                } else
                {
                    printf("发送不可靠信号SIGINT成功!
    ");
                }
            }
            for (i = 0; i < 3; i++)
            {
                v2.sival_int = 301 + i;
                ret = sigqueue(getppid(), SIGRTMIN, v2);
                if (ret != 0)
                {
                    printf("发送可靠信号SIGTMIN失败! error message:%s
    ", strerror(errno));
                } else
                {
                    printf("发送可靠信号SIGTMIN成功!
    ");
                }
            }
            //发送SIGUSR1信号
            if (kill(getppid(), SIGUSR1) != 0)
            {
                printf("kill() failed ! error message;%s
    ", strerror(errno));
            }
            exit(0);
        }
        //父进程
        int res = 0, status = 0;
        while (1)
        {
            res = wait(&status);
            if (res == -1)
            {
                if (errno == EINTR)
                {
    
                    continue;
                }
                break;
            }
        }
        while (1)
        {
            sleep(1);
        }
        return 0;
    }

    一:SIGINT是不可靠信号。发送了3次父进程只接收到1次,SIGRTMIN是可靠信号,发送了3次父进程接收到3次信号。
    二:对于可靠信号,Linux内核会缓存可靠信号,Linux内核可以缓存8192(各个Linux版本不同)条可靠信号;对于不可靠信号,Linux只能缓存一条不可靠信号。
    三:执行命令行: ulimit -a
    查看Linux支持的信号性能参数
    四:发送信号的数量超过系统上限,将会发送失败

     

  • 相关阅读:
    借鉴文章记录
    三方框架
    常用第三方库记录
    ios block 类型
    ios runtime部分事例方法说明
    ios url网址相关问题解说
    mysql迁移数据库函数中的坑
    mysql的事务隔离级别
    MySQL数据库的默认隔离级别为什么是可重复读
    实时查看mysql连接数
  • 原文地址:https://www.cnblogs.com/zhanggaofeng/p/6092379.html
Copyright © 2011-2022 走看看