nixp.ru v3.0

20 января 2017,
пятница,
04:44:35 MSK

DevOps с компанией «Флант»
Kondor написал 12 апреля 2006 года в 22:30 (346 просмотров) Ведет себя как мужчина; открыл 4 темы в форуме, оставил 15 комментариев на сайте.

Есть демон на объектах (C++). В нем есть основной цикл (mainloop()), в котором происходит прослушивание сокета. Есть метод endwork(), который освобождает все ресурсы, закрывает сокет и т.д. Хочу сделать возможность запланированного останова демона по сигналу.

Меня интересует, как обработать в экзмепляре объекта сигнал, скажем, SIGUSR1, что бы вызывался метод endwork()? Соответственно, регистрация сигнала signal(SIGUSR1, endwork) не проходит по понятным причинам.

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

Longobard

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

Kondor
LONGOBARD
Я бы попробовал вместо указателя на функцию подсунуть регистратору функтор, связанный с нужным обьектом.

Но у нас же signal() функция не на шаблонах, поэтому, imho не сработает :/. Пока решил вопрос с ипользованием глобальной переменной.

Longobard
Kondor
Но у нас же signal() функция не на шаблонах

И что? Loki::Functor имеет семантику указателя на функцию, должно сработать. Но не гарантирую, не пробовал его вешать на обработчик сигнала :)

decvar

а разве нельзя сделать signal(SIGUSR1, MyObject::endwork) ?

Longobard
decvar
а разве нельзя сделать signal(SIGUSR1, MyObject::endwork) ?

Тогда уж MyClass::endwork. И это будет работать как обычный статический метод. А тут (как я понял) человеку нужно вызвать метод определенного обьекта.

Kondor
а разве нельзя сделать signal(SIGUSR1, MyObject::endwork) ?


LONGOBARD
Тогда уж MyClass::endwork. И это будет работать как обычный статический метод. А тут (как я понял) человеку нужно вызвать метод определенного обьекта.

Нет, мне нужно вызывать метод текущего объекта. Например, при signal(SIGUSR1, endwork) g++ выдает:

test2.cc: In member function `virtual void MyDaemon::AfterDaemonize()':
test2.cc:68: error: argument of type `void (MyDaemon::)(int)' does not match `
   void (*)(int)'
make: *** [test] пЫЙВЛБ 1

А при signal(SIGUSR1, MyDaemon::endwork):

test2.cc: In member function `virtual void MyDaemon::AfterDaemonize()':
test2.cc:68: error: no matches converting function `endwork' to type `void
   (*)(int)'
test2.cc:47: error: candidates are: void MyDaemon::endwork(int)
make: *** [test] пЫЙВЛБ 1

Соответственно endwork() описана как void MyObject::endwork(int signum), т.е. попадает под определение sighandler_t, и установка обработчика происходит из метода AfterDaemonize().

myst

Что касается functor-ов — дык, это тоже самое, что и функция получится. Какая разница — obj.method() или obj.operator()? Ни какой. Я думаю, что надо сделать методу, который передаётся в signal, extern «C».

iliya
Kondor
Соответственно endwork() описана как void MyObject::endwork(int signum), т.е. попадает под определение sighandler_t, и установка обработчика происходит из метода AfterDaemonize().

А ты так нипиши:

class MyDaemon {
...
static void endwork(int signum);
...
};

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

rgo

а посмотрите на библиотечку libsigc++, она умеет делать врапперы на методы классов, с тем чтобы их потом в extern «C» функции передавать без SEGFAULT’ов. На этой библиотечке gtkmm построена, та которая обёртка над gtk.

Kondor

Ладно, тогда оставлю как есть, т.е. via global variable. Неохота городить огород. Просто мне кажется не совсем корректным и красивым использование глобальных переменных. Но я тут подумал, что экзмепляр объекта может быть только один (ведь это демон же, куда их больше-то? ;)), то можно обойтись и единственной статической глобальной переменной. Всем спасибо за участие в обсуждении вопроса.

Longobard
Kondor
Но я тут подумал, что экзмепляр объекта может быть только один (ведь это демон же, куда их больше-то? ;))

Чтобы были 100% гарантии уникальности обьекта, используй синглтоны (я предпочитаю Loki::Singleton).

decvar

ты ваще предпочитаешь Loki :)

Longobard
decvar
ты ваще предпочитаешь Loki :)

Не, я еще и boost люблю, локи не панацея :)

myst

Я и STL не люблю… текут они все, текут. Лучше plain C, причём мне хватило бы и K&R. :)

Longobard
myst
Я и STL не люблю… текут они все, текут.

STL течёт? А доказать сможешь?

myst

STL-ов несколько, кстати. :) Мелкософтовский течёт, ну или тёк.

Longobard
myst
STL-ов несколько, кстати. :)

А который в libstdc++  - он течет? Если да — то покажи код, демонстирующий утечку. Мб ты просто не умеешь правильно использовать stl контейнеры? Почему-то у меня именно такое ощущение…

myst

Ой вот только не надо, а? Умею я, умею использовать STL-контейнеры. Но мелкосовтовский тёк. Если найду код, то прогоню и на GCC — проверю. О результатах доложу :)

Longobard
myst
Ой вот только не надо, а? Умею я, умею использовать STL-контейнеры. Но мелкосовтовский тёк. Если найду код, то прогоню и на GCC — проверю. О результатах доложу :)

Давай, жду кода.

И все-таки мне кажется что ты не умеешь ими пользоваться…

myst

Офигеть. Тяжела наука… А что там уметь-то?

Longobard
myst
Офигеть. Тяжела наука… А что там уметь-то?

Ты код сначала покажи ;)

Например у тебя вектор указателей, и ты удаляешь элемент вектора. А удалить обьект, на который указывает указатель из этого элемента — не забываешь?

В общем там много таких вот вещей, про которые не надо забывать :) Это я только один пример привел, еще есть.

SHOW ME THE CODE! ;)

myst

Блин, откопаю — покажу. Он в закромах корпорации. У меня на ноуте его нет.

ecobeingecobeing.ru
Экология и вегетарианство на благо всем живым существам Планеты.