LINUX.ORG.RU

boost signal handling

 ,


0

3

Доброго времени суток!

Встала задача асинхронной обработки сигналов приложением при помощи Boost.Asio, при этом не надо, чтобы приложение сразу выходило после обработки первого сигнала, а дальше ждало новых сигналов. В документации написано, что метод run() класса boost::asio::io_service не должен вызываться из обработчика сигналов (точнее, до того, как сигнал будет обработан), но это ок, также там написано, что для таких целей существует метод reset, который должен вызываться перед каждым последующим вызовом run(). Поясните, почему этот код не робит и как его поправить? Вроде все согласно документации...

io_service_.run();
for(;;)
{
   io_service_.reset();
   io_service_.run();
}
★★

С таким участком кода ничего не понятно. Нужен полный пример.

anatoly
()

А если попытаться угадать вслепую, то, возможно, так будет работать, как нужно:

io_service::work work_(io_service_);
io_service_.run();

anatoly
()
Ответ на: комментарий от aido

Обработчик, переданный в signals_.async_wait, выполняется только один раз. Для обработки нового сигнала нужно функцию async_wait заново вызывать.

anatoly
()

Нужно разобраться, пишете Вы синхронную или асинхронную программу. А шаблон «дождаться первого сигнала, а потом в коллбеке что-то еще ждать» - такого не бывает. io_service.run() вызывается один раз ( по крайней мере, достаточно этого ). Коллбеки могут иметь стейт, если callback создан при помощи std::bind или boost::bind. В зависимости от этого стейта, управляете логикой обработки сигналов.

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

Пишу асинхронную. Так я в шапке поста и написал, как происходит сейчас.

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

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

О каком стэйте Вы говорите?

aido ★★
() автор топика
Последнее исправление: aido (всего исправлений: 2)
Ответ на: комментарий от anatoly

Ну я пока не аплоадил этот эксперимент на гитхаб. по факту я строчку с work добавил тупо перед io_service_.run() и запустил прогу. Эффект был тот, что прога перестал отжирать ресурсы процессора после выхода из петли, но на сигналы (после прихода первого) реагировать не начала.

Счас еще пару часов поиграюсь и отпишу, что вышло.

Скажите еще, надо каждый раз сигналы перерегистрировать или достаточно в конце обработчика сигналов дописать async_wait(...)?

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

Прошу на гитхаб.

Сейчас постоянно шлется sighup потомку... По крайней мере он так на это реагирует.

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

Че-то я ваще нихрена не понимаю, как это заставить работать. Уже всё перепробовал, всю документацию на signal_set вдоль и поперек прочитал...

То родитель шлет потомку SIGHUP, не останавливаясь, то потомок падает в рандомный момент (если добавить строки clear(); cancel(); RegisterSignals();, то есть полностью заново зарегистрировать все сигналы). Такое ощущение, что в io_service есть какая-то переменная, которую мне нужно обнулить, но доступа до нее у меня нету.

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

Я с програмированием сигналов под linux не особо знаком, а общая логика работы демона от меня ускользает.

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

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

Вроде получилось поправить!

теперь основной вопрос: а нужен ли был мне буст? Просто если хочется делать самоотладку, то хэндлер должен принимать помимо номера сигнала еще и адрес последней инструкции и siginfo_t-структуру. boost, как я понял, этого не позволяет сделать =( или я не прав?

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

По умолчанию, вроде бы, не позволяет.

Для того, чтобы в обработчик передавать дополнительные параметры, нужно немного модифицировать класс detail::signal_set_service , либо написать собственный signal_set и сервис для него.

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

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

ну там еще отдельно будет сервак и часть, которая «вечно что-то делает».

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

просто в asio я начал копаться в целях изучения буста, и пока с ходу не могу сказать, где она действительно полезна, а где вообще не нужна.

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

Имхо, если логика, построенная на обработке асинхронных событий, планируется сложной, то нужна.

В С++17 asio планируют в стандарт добавить, так что скоро это будет уже не буст.

anatoly
()
Ответ на: комментарий от aido

просто в asio я начал копаться в целях изучения буста

По моему, asio - это вещь в себе. Ведь эта либа и отдельно от буста доступна. Впрочем, сам буст - тоже не нечто монолитное, а набор библиотек.

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

так а как тогда можно будет средствами С++17 получить sigact_t структуру при получении сигнала? Тут никак не выкинуть signal.h из-за posix-совместимости.

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

Я про С++17 к слову упомянул. К теме обработки сигналов это не имело отношения.

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