LINUX.ORG.RU

Надёжная проверка сигнала

 


0

0

Сервер большую часть времени проводит в msgrcv. Нужно, чтобы он корректно завершался по SIGTERM, поэтому в обработчике сигнала я устанавливаю глобальный флаг, который потом проверяю:

void sig(int)
{
    quit = 1;
}

int main()
{
    for(;;) {
        if(quit)
            throw SigException();
        // здесь может прийти сигнал
        msgrcv(...);
        if(quit)
            throw SigException();

        some_work();
        msgsnd(...);
    }
}
Всё бы хорошо, но если сигнал придёт в указанный момент, то обнаружится это только при поступлении очередного запроса, что создаёт впечатление потерянного сигнала. Можно ли избежать этого?

★★★★

Последнее исправление: unsigned (всего исправлений: 1)
Ответ на: комментарий от unsigned

Ага, понял. Можно вместо обработчика сигнала запускать нить, и вызывать msgsnd() из нее. С флагом что-то сложно придумать.

AptGet ★★★
()
Ответ на: комментарий от AptGet

Выделить отдельную нить под обработку сигналов? Выглядит сложнее, чем должно быть... но, видимо, с сигналами всегда так.

Ещё очко в пользу сокетов, с другой стороны.

unsigned ★★★★
() автор топика
Ответ на: комментарий от AptGet

как вариант man mq_overview

Polling message queue descriptors
       On Linux, a message queue descriptor is actually a file descriptor, and
       can be monitored using select(2), poll(2), or epoll(7).   This  is  not
       portable.

nanoolinux ★★★★
()
Ответ на: комментарий от nanoolinux

Я хотел предложить POSIX mq, но не был уверен, что стандартные функции мультиплексирования с ней работают.

AptGet ★★★
()
Ответ на: комментарий от nanoolinux

Значит ли это, что write работает с очередями POSIX?

В любом случае, у меня SysV, потому что используется диспетчеризация по типу.

unsigned ★★★★
() автор топика
Ответ на: комментарий от unsigned

согласно документации - да. но только под линуксом.

nanoolinux ★★★★
()
Ответ на: комментарий от unsigned

или можешь семафор прикрутить дополнительно, msgrcv сделать с IPC_NOWAIT, а в обработчике сигнала добавлять семафор, но в очередь ничего не класть. ждёшь на семафоре, как только проснулся - читаешь. если msgrcv вернётся с ENOMSG, то это будет значить, что пришла пора. только надо будет ещё модифицировать код, ответсвенный за отправку сообщений, что бы он тоже семафору sem_post делал.

nanoolinux ★★★★
()

Вам нужен pselect(2).

The reason that pselect() is needed is that if one wants to wait for either a signal or for a file descriptor to become ready, then an atomic test is needed to prevent race conditions.

Подробно тут: http://stackoverflow.com/questions/6962150/catching-signals-while-reading-fro...

В вашем случае вы можете безопасно проверять флаг при замаскированном SIGTERM, а блокироваться не на msgrcv(), а на pselect(), который будет атомарно проверять наличие сигнала.

Другой способ: использовать libev или libevent: они реализуют event loop, в который можно добавлять обработчики и для сигналов и для сокетов.
При этом выполняться все будет сериализованно.

gv
()

Если есть возможность не использовать SysV IPC - не используй. Они в в модель программирования Unix не интегрированы никак.

tailgunner ★★★★★
()
Ответ на: комментарий от gv

Поправка: выше сказали про sysvipc, и до меня дошло, что pselect() будет работать только с позиксными очередями:

mq_overview(7)

On Linux, a message queue descriptor is actually a file descriptor, and can be monitored using select(2), poll(2), or epoll(7). This is not portable.

gv
()
Ответ на: комментарий от tailgunner

Возможность как бы есть, просто их возможность выборки по заданному типу сильно облегчает жизнь.

А как бы мне помогли POSIX mq (если без линуксизмов)?

unsigned ★★★★
() автор топика
Ответ на: комментарий от unsigned

А как бы мне помогли POSIX mq (если без линуксизмов)?

Без линуксизмов (ожидания в poll) POSIX mq - это просто вариация на тему SysV mq.

tailgunner ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.