2013-11-11 2 views
2

Я работаю на языке C. Я пытаюсь поймать и обработать два различных сигнала:Сделать сигнальный переключатель действием другого сигнала

  • INT: когда этот сигнал ловится, действие1 или action2 срабатывает
  • QUIT: когда этот сигнал ловится, действие сигнала INT является включен (действие1 ->действие2 или действие2 ->действие1)

Значение сигнала по умолчанию INT установлено на action1.

В моем коде, switchaction функция также вызывается QUIT сигнал, но не оказывает никакого влияния на действия сигнала INT: s

#include <signal.h> 
#include <stdio.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <string.h> 

typedef void (*sighandler_t)(int); 
sighandler_t prev_handler; 

void action1(int n){ 
    printf("First message\n"); 
} 
void action2(int n){ 
    printf("Second message\n"); 
} 

void switchaction(int n){ 
    printf("Switch action\n"); 
    prev_handler=action2; 
} 

int main() { 
    prev_handler = action1; 
    printf("PID: %d\n", getpid()); 
    prev_handler= signal(SIGINT,prev_handler); 
    signal(SIGQUIT,switchaction); 

    travail(); //This function never ends 
} 

Вы бы иметь ни малейшего представления о том, что неправильно в моем коде?

Спасибо,

Yann

+0

BTW, вы не работаете в C, а в C и Posix (или C и Linux) –

ответ

2

Ваш системный вызов

prev_handler= signal(SIGINT,prev_handler); 

устанавливает обработчик сигнала к значению prev_handler переменной в данный момент вы выполняете signal системный вызов. Изменение (после) значения prev_handler не меняет обработку сигнала SIGINT. Другими словами, signal (и большинство вызовов C) имеют семантику call by value. Если вы вызываете signal один раз, ядро ​​сохраняет тот же обработчик (до тех пор, пока вы не вызовете signal с тем же номером сигнала или до тех пор, пока не назовете sigaction(2) и т. Д.).

Прочтите внимательно (при условии, что вы находитесь на Linux) страницы и signal(2).

Я бы вместо того, чтобы определить

volatile sig_atomic_t howhandle; 

void switchaction(int n __attribute__((unused))) { 
    if (howhandle) 
     howhandle = 0; 
    else 
     howhandle = 1; 
} 

void handleint (int n) { 
    if (howhandle) action1(n); else action2(n); 
} 

и установить только

signal(SIGINT, handleint); 
signal(SIGQUIT, switchaction); 

Кроме того, заметьте, что призывающей printf внутри обработчика неправильно (потому что printf является не асинхронных SIGNAL- безопасную функцию, но вы вызываете ее в action1, вызывается handleint ...). Снова прочитайте signal(7)

Вы должны иметь некоторые другие переменные volatile sig_atomic_t и проверить (и очистить их) в соответствующих местах внутри вашей рабочей функции travail, но установите их только в ваших обработчиках сигналов. Установка переменной volatile sig_atomic_t - это в значительной степени единственное, что можно надежно сделать внутри обработчика сигнала.

Если вы принимаете конкретные решения Linux, узнайте больше о signalfd(2) (и используйте также poll(2) ...). Читайте также Advanced Linux Programming.