2017-06-11 65 views
6

Funkcja pause() blokuje się, dopóki nie nadejdzie sygnał. Zakładając, że proces otrzymał sygnał i wstrzymano(), czy procedura obsługi sygnału zostanie wykonana przed kodu następującego po wywołaniu , czy wynik jest nieoczekiwany?obsługa sygnału pauzy()

Przykład:

void sigusr1_handler() 
{ 
    // .. handler code 
} 

void main() 
{ 
    // .. bind handler to SIGUSR1 

    pause(); // wait for SIGUSR1 
    // some more code 
} 

znaczy „trochę więcej kodu” będzie zawsze wykonywany posigusr1_handler() zakończyła, czy tam jest sytuacja wyścigu? Jeśli tak, jakie jest rozwiązanie?
nie mogę myśleć o niczym oprócz zajętości czekania, ale potem przerwa nie będzie w ogóle potrzebne ..

+0

"lub wynik jest nieoczekiwany" - Skąd mamy wiedzieć, czego się spodziewać? – Olaf

Odpowiedz

7

Powołując z the man page for pause(2):

pauzy() tylko powraca, gdy sygnał złapany i zwrócono sygnał. W takim przypadku pauza() zwraca -1, a errno jest ustawione na EINTR.

Możesz być pewien, że twój program obsługi sygnału działa przed some more code.

3

Sterowniki sygnału nie działają jednocześnie; przerywają wątek, który je obsługuje, a przerwany przepływ działa tylko wtedy, gdy procedura obsługi sygnału wraca.

Jednak mogą występować inne warunki wyścigu związane z tym przykładem; z nielicznym pseudokodem i nie pełnym wyjaśnieniem twojego przypadku użycia, trudno powiedzieć. Na przykład inny sygnał może nadejść i przerwać sygnał, zanim twój sygnał zadziała, a wtedy twój przewodnik może zakończyć pracę później, niż się spodziewałeś.

Istnieje kilka sposobów, „prawo”, aby to zrobić zamiast:

  • write pojedynczy bajt Do pipe w obsługi sygnału i read z niego w głównym strumieniu wykonania.
  • sem_post semafor od obsługi sygnału i sem_wait w głównym strumieniu wykonania.
  • Użyj sigwaitinfo lub sigtimedwait zamiast obsługi sygnału.
  • Nadal używać pause, ale w pętli:

    while(!signal_handler_finished) pause(); 
    

    gdzie signal_handler_finished ma typ volatile sig_atomic_t i jest ustawiona na wartość niezerową w obsługi sygnału.

+0

Dzięki. Używam również sig_mask do blokowania innych sygnałów w obsłudze sygnału. Właśnie dlatego uprościłem mój przykład. Chciałem tylko upewnić się, że programy obsługi sygnału nie działają w "stylu wątku" i tym samym podlegają warunkom wyścigu. Więc w moim przypadku przerwa powinna działać dobrze. Dzięki za dodatkowe info! – user3599803