简体   繁体   中英

Is it possible to send signals through IPC Message Passing Queue?

I have tried calling kill from process A to process B and the process B has successful reacted to the signal. The problem is I don't want to send signals from the kill function directly for two reasons:

1) Sometimes the process A may not have the permissions, ex. process B is ran by another user

2) I want to be able to send signals from A to B through the message queue

I am creating a message queue from which I send "objects" of the following structure

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

I want to know if it is possible for process A to signal B through IPC Message Passing. I know I can achieve this by sending the signal type into the message_text from process A to B and then inside the process B check the type of the signal and act properly but I was wondering if there is another way.

Would this be possible by passing sigaction objects as messages:

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

I know this is completely infeasible but this is what I am trying to achieve. Thank you

Message queues can't achieve how signals do. With signal it is possible to asynchronously interrupt or kill process but with message queue when receiving process checks message or wait on it and exits after receiving message, it actually will ignore that message rest of path of execution(synchronous). But, It is possible to achieve with threads.

If you were using a POSIX message queues (using mq_send/mq_receive), then process B can request (with mq_notify) to be sent a signal every time a message is sent to the message queue. However, your example seems to be using a SYSV legacy message queue (msgsnd) which does not suppport any kind of notify.

Based upon your comments it seems that you want B to be able to receive messages but when it receives a "signal" message it needs to act like it received a regular signal. You mentioned that the B needed to react to SIGTERM or SIGINT from the "signal" message.

The way to achieve this is depends upon using POSIX message queues or System V message queues.

Either way it doesn't seem that you want to use polling of the message queue by the main thread of B as that would add to much latency to responding to the "signal" message.

So with POSIX message queues you can use mq_notify() to run either a thread or raise a signal that a new message has arrived. Otherwise B can use a thread (or even fork() ) to poll the message queue.

After a "signal" message is received you have a couple of options. A) You can use either kill or raise in B to send a signal of the correct type to itself (or parent in case of fork ), or B) just call a function that does what you want (that sort of thing).

Process A can send a "signal" message whenever it wants. But you need to understand that if you are using named queues they are persistent. That is that A can send a "signal" message before B even starts, and then when B starts that message is waiting there. Depending on how the message queue is made it can be N messages deep and have older messages in the queue. One way to deal with that is for B to empty the queue before processing any of the messages.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM