2015-12-15 7 views
2

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

Код

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

+0

Связанные вопрос: https://stackoverflow.com/q/343219/1340631 – scai

ответ

2

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

Причина в том, что все функции имеют «подразумеваемый/скрытый» аргумент указателя this. Если мы «сплющенные» из вашего определения обработчика, чтобы произвести эквивалент C, это будет выглядеть так:

void SocketServer::signalHandler(SocketServer *this,int sig); 

The 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. Кроме того, когда в обработчике сигналов есть ограниченное количество вещей, которые вам разрешено делать. Например, допустимы no.

Вот лучший способ осуществить это:

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; 
}