Обработка прерываний с нестатической функцией-членом

Я пытаюсь сделать обработку прерываний с помощью функции-члена из класса.

Код

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 пример. Я думаю, я могу использовать глобальную переменную и глобальную функцию для выполнения этой работы, но есть ли какие-нибудь мысли по поводу этого с помощью функции-члена?

2

Решение

Нет вы можете не сделай это.

Причина в том, что все член функции имеют «подразумеваемый / скрытый» 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;
}
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]