Можно ли отправлять сигналы через очередь передачи сообщений IPC? - PullRequest
0 голосов
/ 26 декабря 2018

Я попытался вызвать kill из процесса A в процесс B, и процесс B успешно отреагировал на сигнал.Проблема в том, что я не хочу отправлять сигналы из функции kill напрямую по двум причинам:

1) Иногда процесс A может не иметь разрешений, напр.процесс B запущен другим пользователем

2) Я хочу иметь возможность отправлять сигналы от A к B через очередь сообщений

Я создаю очередь сообщений, из которой я отправляю "объекты"следующей структуры

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

Я хочу знать, возможно ли для процесса A сигнализировать B через передачу сообщений IPC.Я знаю, что могу достичь этого, отправив тип сигнала в message_text из процесса A в B, а затем внутри процесса B проверить тип сигнала и действовать правильно, но мне было интересно, есть ли другой способ.

Возможно ли это, передавая объекты sigaction в виде сообщений:

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

Я знаю, что это абсолютно невозможно, но это то, чего я пытаюсь достичь.Спасибо

Ответы [ 3 ]

0 голосов
/ 26 декабря 2018

Если вы использовали очереди сообщений POSIX (используя mq_send / mq_receive), то процесс B может запрашивать (с помощью mq_notify) отправку сигнала каждый раз, когда сообщение отправляется в очередь сообщений.Однако в вашем примере, похоже, используется устаревшая очередь сообщений SYSV (msgsnd), которая не поддерживает никаких уведомлений.

0 голосов
/ 26 декабря 2018

Исходя из ваших комментариев, кажется, что вы хотите, чтобы B мог получать сообщения, но когда он получает "сигнальное" сообщение, ему нужно действовать так, как будто он получил обычный сигнал.Вы упомянули, что B должен реагировать на SIGTERM или SIGINT из сообщения "signal".

Способ достижения этого зависит от использования очередей сообщений POSIX или очередей сообщений System V.

В любом случае кажется, что вы не хотите использовать опрос очереди сообщений основным потоком B, поскольку это увеличит задержку при ответе на "сигнальное" сообщение.

Таким образом, с очередями сообщений POSIX вы можете использовать mq_notify(), чтобы запустить поток или подать сигнал о получении нового сообщения.В противном случае B может использовать поток (или даже fork()) для опроса очереди сообщений.

После получения «сигнального» сообщения у вас есть несколько вариантов.A) Вы можете использовать kill или raise в B, чтобы отправить сигнал правильного типа себе (или родительскому в случае fork), или B) просто вызвать функцию, которая делает то, что вы хотите (чтовроде вещи).

Процесс A может отправлять «сигнальное» сообщение, когда захочет.Но вы должны понимать, что если вы используете именованные очереди, они являются постоянными.То есть A может отправлять «сигнальное» сообщение еще до того, как B запускается, а затем, когда B запускается, это сообщение ожидает там.В зависимости от того, как устроена очередь сообщений, она может быть N сообщений глубиной и иметь более старые сообщения в очереди.Один из способов справиться с этим - очистить очередь B перед обработкой любого из сообщений.

0 голосов
/ 26 декабря 2018

Очереди сообщений не могут достичь того, как работают сигналы.С помощью сигнала можно асинхронно прерывать или уничтожать процесс, но с помощью очереди сообщений при получении процесс проверяет сообщение или ожидает его и завершает работу после получения сообщения, фактически игнорируя это сообщение по остальному пути выполнения (синхронно).Но можно добиться с помощью потоков.

...