Я пытаюсь сделать обработку прерываний с помощью функции-члена из класса.
Код
signal(SIGABRT, socketServer.signalHandler);
где определение signalHandler
является
public:
void SocketServer::signalHandler(int sig) {
logger.info("Receive SIG"+to_string(sig)+" Stopping server now...");
stop();
}
Когда я компилирую код, я получаю сообщение об ошибке
main.cpp:32:32: error: reference to non-static member function must be called
signal(SIGABRT, socketServer.signalHandler);
Я пытаюсь поймать SIGABRT
используя это signalHandler
функционировать и очистить и остановить socketServer
пример. Я думаю, я могу использовать глобальную переменную и глобальную функцию для выполнения этой работы, но есть ли какие-нибудь мысли по поводу этого с помощью функции-члена?
Нет вы можете не сделай это.
Причина в том, что все член функции имеют «подразумеваемый / скрытый» this
указатель аргумента. Если бы мы «сгладили» ваше определение обработчика для получения эквивалента C, это выглядело бы так:
void SocketServer::signalHandler(SocketServer *this,int sig);
signal
функция [в C] ничего не знает об этом [каламбур]. Если это скомпилировано, обработчик будет вызван с sig
вдаваясь в this
аргумент и не sig
аргумент.
Итак, вы действительно должны сделать:
SocketServer my_global_server;
void
my_handler(int sig)
{
my_global_server.signalHandler(sig);
}
int
main(void)
{
signal(SIGABRT,my_handler);
return 0;
}
На самом деле, выше довольно опасно, потому что my_global_server
может быть в неопределенном состоянии, когда вызывается обработчик сигнала, вызывая UB. Кроме того, в обработчике сигналов есть ограниченное количество вещей, которые вам разрешено делать. Например, нет манипуляции с кучей разрешены.
Вот лучший способ реализовать это:
volatile int signal_flag;
SocketServer my_global_server;
void
my_handler(int sig)
{
signal_flag = sig;
}
int
main(void)
{
signal(SIGABRT,my_handler);
while (! signal_flag) {
...
}
my_global_server.signalHandler(signal_flag);
return 0;
}
Других решений пока нет …