加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

在Linux上以相反顺序接收的实时信号

发布时间:2020-12-14 00:06:13 所属栏目:Linux 来源:网络整理
导读:该程序向其自身发送实时信号并处理它们.一旦处理完毕,它就会按照收到的顺序输出收到的信号. $cat realtime.c#include signal.h#include stdio.h#include unistd.h#include stdlib.hint received_signals[10];int received_signals_value[10];int received_si
该程序向其自身发送实时信号并处理它们.一旦处理完毕,它就会按照收到的顺序输出收到的信号.

$cat realtime.c
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int received_signals[10];
int received_signals_value[10];
int received_signals_count = 0;

void real_time_handler(int sig_number,siginfo_t * info,void * arg __attribute__ ((unused)))
{
    received_signals[received_signals_count] = sig_number - SIGRTMIN;
    received_signals_value[received_signals_count] = info->si_value.sival_int;
    ++received_signals_count;
}

void send_real_time_signal(int sig_number,int value)
{
    union sigval sig_value;

    printf("Sending signal SIRTMIN+%d,value %dn",sig_number,value);
    sig_value.sival_int = value;
    if (sigqueue(getpid(),sig_number + SIGRTMIN,sig_value) < 0) {
        perror("sigqueue");
        exit(EXIT_FAILURE);
    }
}

int main()
{
    struct sigaction action;
    sigset_t set;
    int i;

    // Handler setup
    action.sa_sigaction = real_time_handler;
    sigemptyset(&action.sa_mask);
    action.sa_flags = SA_SIGINFO;
    if ((sigaction(SIGRTMIN + 1,& action,NULL) < 0)
     || (sigaction(SIGRTMIN + 2,NULL) < 0)
     || (sigaction(SIGRTMIN + 3,NULL) < 0)) {
        perror("sigaction");
        exit(EXIT_FAILURE);
    }

    // Block all signals
    sigfillset(&set);
    sigprocmask(SIG_BLOCK,&set,NULL);

    send_real_time_signal(1,0);
    send_real_time_signal(2,1);
    send_real_time_signal(3,2);
    send_real_time_signal(1,3);
    send_real_time_signal(2,4);
    send_real_time_signal(3,5);
    send_real_time_signal(3,6);
    send_real_time_signal(2,7);
    send_real_time_signal(1,8);
    send_real_time_signal(3,9);

    // Unblock all signals
    sigfillset(&set);
    sigprocmask(SIG_UNBLOCK,NULL);

    // To make sure we're handling all signals before resuming
    sleep(1);

    // Display results
    for (i = 0; i < received_signals_count; ++i) {
        printf("Received signal SIGRTMIN+%d,received_signals[i],received_signals_value[i]);
    }

    return EXIT_SUCCESS;
}

我一直得到以下输出:

$gcc -Wall -Wextra -O2 -o realtime realtime.c
$./realtime
Sending signal SIRTMIN+1,value 0
Sending signal SIRTMIN+2,value 1
Sending signal SIRTMIN+3,value 2
Sending signal SIRTMIN+1,value 3
Sending signal SIRTMIN+2,value 4
Sending signal SIRTMIN+3,value 5
Sending signal SIRTMIN+3,value 6
Sending signal SIRTMIN+2,value 7
Sending signal SIRTMIN+1,value 8
Sending signal SIRTMIN+3,value 9
Received signal SIGRTMIN+3,value 2
Received signal SIGRTMIN+3,value 5
Received signal SIGRTMIN+3,value 6
Received signal SIGRTMIN+3,value 9
Received signal SIGRTMIN+2,value 1
Received signal SIGRTMIN+2,value 4
Received signal SIGRTMIN+2,value 7
Received signal SIGRTMIN+1,value 0
Received signal SIGRTMIN+1,value 3
Received signal SIGRTMIN+1,value 8

这与signal(7)(http://man7.org/linux/man-pages/man7/signal.7.html)中的内容相矛盾:

Real-time signals are delivered in a guaranteed order. Multiple real-time signals of the same type are delivered in the order they were sent. If different real-time signals are sent to a process,they are delivered starting with the lowest-numbered signal. (I.e.,low-numbered signals have highest priority.) By contrast,if multiple standard signals are pending for a process,the order in which they are delivered is unspecified.

据我了解,我应该得到:

$./realtime
Sending signal SIRTMIN+1,value 9
Received signal SIGRTMIN+1,value 8
Received signal SIGRTMIN+2,value 7
Received signal SIGRTMIN+3,value 9

我已经快速浏览了一下Linux内核源代码,但却找不到处理实时信号的地方.

我做错了什么/遗失了什么或者手册页是不准确的?

解决方法

您的问题是您允许其他信号中断正在运行的信号处理程序:

sigemptyset(&action.sa_mask);

sa_mask字段指定不允许中断此处理程序执行的信号集.

这意味着您可以获得SIGRTMIN 1,在您可以执行任何操作之前,您将获得另一个较低优先级的信号,然后您可以开始处理该信号.然后该信号又被另一个信号中断,依此类推.

要解决此问题,请禁止任何其他信号中断您的处理程序:

sigfillset(&action.sa_mask);

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读