我尝试从进程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);
//...
我知道这是完全不可行的,但这是我想要实现的目标。谢谢
答案 0 :(得分:1)
消息队列无法实现信号的处理方式。通过信号,可以异步中断或杀死进程,但是当接收进程检查消息或等待消息并在接收到消息后退出时,通过消息队列,实际上它将忽略该消息的其余执行路径(同步)。但是,可以通过线程来实现。
答案 1 :(得分:1)
如果您正在使用POSIX消息队列(使用mq_send / mq_receive),则每次将消息发送到消息队列时,进程B可以请求(使用mq_notify)发送信号。但是,您的示例似乎正在使用不支持任何种类的通知的SYSV旧消息队列(msgsnd)。
答案 2 :(得分:1)
根据您的评论,您似乎希望B能够接收消息,但是当B收到“信号”消息时,它需要像接收到常规信号那样工作。您提到B需要对“信号”消息中的SIGTERM
或SIGINT
做出反应。
实现此目标的方法取决于使用POSIX消息队列或System V消息队列。
无论哪种方式,似乎都不想使用B的主线程对消息队列进行轮询,因为那样会增加响应“信号”消息的延迟。
因此,对于POSIX消息队列,您可以使用mq_notify()
运行线程或发出新消息到达的信号。否则,B可以使用线程(甚至是fork()
)来轮询消息队列。
在收到“信号”消息后,您有两种选择。 A)您可以在B中使用kill
或raise
向自身(或在fork
的情况下为父)发送正确类型的信号,或者B只需调用一个函数做你想要的(那种事情)。
进程A可以随时发送“信号”消息。但是您需要了解,如果使用命名队列,它们将是持久的。也就是说,A可以在B甚至开始之前发送“信号”消息,然后当B开始时,该消息在那里等待。根据创建消息队列的方式,它可以是N条消息,并且队列中可以包含较旧的消息。一种解决方法是让B在处理任何消息之前清空队列。