是否可以通过IPC消息传递队列发送信号?

时间:2018-12-25 23:24:56

标签: c linux signals ipc

我尝试从进程A向进程B调用kill,而进程B已成功响应该信号。问题是我不想直接从kill函数发送信号,原因有两个:

1)有时进程A可能没有权限,例如。进程B由另一个用户运行

2)我希望能够通过消息队列从A到B发送信号

我正在创建一个消息队列,从中发送具有以下结构的“对象”

typedef struct msg {
    long message_type;
    char message_text[SIZE];
}message;

我想知道进程A是否可以通过IPC消息传递向B发出信号。我知道我可以通过将信号类型从进程A发送到message_text到B,然后在进程B内部检查信号的类型并正确执行操作来实现此目的,但是我想知道是否还有另一种方法。

是否可以通过将sigaction对象作为消息传递来实现?

struct sigaction as;
//...
msgsnd(queue_id, &as, length, IPC_NOWAIT);
//...

我知道这是完全不可行的,但这是我想要实现的目标。谢谢

3 个答案:

答案 0 :(得分:1)

消息队列无法实现信号的处理方式。通过信号,可以异步中断或杀死进程,但是当接收进程检查消息或等待消息并在接收到消息后退出时,通过消息队列,实际上它将忽略该消息的其余执行路径(同步)。但是,可以通过线程来实现。

答案 1 :(得分:1)

如果您正在使用POSIX消息队列(使用mq_send / mq_receive),则每次将消息发送到消息队列时,进程B可以请求(使用mq_notify)发送信号。但是,您的示例似乎正在使用不支持任何种类的通知的SYSV旧消息队列(msgsnd)。

答案 2 :(得分:1)

根据您的评论,您似乎希望B能够接收消息,但是当B收到“信号”消息时,它需要像接收到常规信号那样工作。您提到B需要对“信号”消息中的SIGTERMSIGINT做出反应。

实现此目标的方法取决于使用POSIX消息队列或System V消息队列。

无论哪种方式,似乎都不想使用B的主线程对消息队列进行轮询,因为那样会增加响应“信号”消息的延迟。

因此,对于POSIX消息队列,您可以使用mq_notify()运行线程或发出新消息到达的信号。否则,B可以使用线程(甚至是fork())来轮询消息队列。

在收到“信号”消息后,您有两种选择。 A)您可以在B中使用killraise向自身(或在fork的情况下为父)发送正确类型的信号,或者B只需调用一个函数做你想要的(那种事情)。

进程A可以随时发送“信号”消息。但是您需要了解,如果使用命名队列,它们将是持久的。也就是说,A可以在B甚至开始之前发送“信号”消息,然后当B开始时,该消息在那里等待。根据创建消息队列的方式,它可以是N条消息,并且队列中可以包含较旧的消息。一种解决方法是让B在处理任何消息之前清空队列。