sigakcja


W informatyce sigaction to funkcja API zdefiniowana przez POSIX , aby dać programiście dostęp do tego, jakie powinno być zachowanie programu podczas odbierania określonych sygnałów systemu operacyjnego .

Ogólny

W systemach operacyjnych typu Unix jednym ze sposobów komunikacji między procesami są sygnały. Gdy jednostka wykonująca ( proces lub wątek ) otrzymuje sygnał z systemu operacyjnego, powinna zareagować w sposób określony w arkuszu danych i konwencjonalnym znaczeniu tego sygnału (np. poprzez zrzucenie danych, zatrzymanie wykonywania, zsynchronizowanie czegoś...).

sigaction () służy do zadeklarowania zachowania programu, jeśli otrzyma on jeden konkretny sygnał niezarezerwowany przez system. Odbywa się to poprzez podanie wraz z wywołaniem systemowym struktury zawierającej między innymi wskaźnik funkcji do procedury obsługi sygnału. Niektóre predefiniowane sygnały (takie jak SIGKILL ) mają zablokowane zachowanie, które jest obsługiwane przez system i nie mogą być nadpisywane przez takie wywołania systemowe.

struktura sigakcji

Standard POSIX wymaga, aby struktura sigaction była zdefiniowana jak poniżej w pliku plik nagłówkowy i powinien zawierać co najmniej następujące pola:

  
	               
	                      
	                          
	
	
	            
 struct  sigaction  {  void  (  *  sa_handler  )(  int  );  /* adres procedury obsługi sygnału */  sigset_t  sa_mask  ;  /* dodatkowe sygnały do ​​zablokowania */  int  sa_flags  ;  /* opcje sygnału */  /* alternatywna procedura obsługi sygnału */  void  (  *  sa_sigaction  )(  int  ,  siginfo_t  *  ,  void  *  );  }; 

Implementacje mogą dowolnie definiować dodatkowe, prawdopodobnie nieprzenośne pola. Składnik sa_handler określa adres funkcji, która ma zostać wywołana, gdy proces odbierze sygnał. Numer sygnału jest przekazywany do tej funkcji jako argument typu integer. Składnik sa_mask określa dodatkowe sygnały, które mają być blokowane podczas wykonywania procedury obsługi sygnału. sa_mask musi być inicjalizowany przez sigemptyset(3). Członek sa_flags określa dodatkowe flagi. sa_sigaction to alternatywna procedura obsługi sygnału z innym zestawem parametrów. Należy określić tylko jeden program obsługi sygnału, albo sa_handler, albo sa_sigaction. Jeśli pożądane jest użycie sa_sigaction zamiast sa_handler, należy ustawić flagę SA_SIGINFO.

Zastąpienie sygnału()

sigaction () zapewnia interfejs dla niezawodnych sygnałów w miejsce zawodnej funkcji signal() . Programy obsługi sygnałów zainstalowane przez signal() zostaną odinstalowane bezpośrednio przed wykonaniem programu obsługi. Dlatego stałe programy obsługi muszą być ponownie instalowane przez wywołanie funkcji signal() podczas wykonywania procedury obsługi, co powoduje zawodność w przypadku odebrania sygnału tego samego typu podczas wykonywania procedury obsługi, ale przed ponowną instalacją. Programy obsługi zainstalowane przez sigaction() Interfejs można zainstalować na stałe, a niestandardowy zestaw sygnałów można zablokować podczas wykonywania procedury obsługi. Sygnały te zostaną odblokowane natychmiast po normalnym zakończeniu procedury obsługi (ale nie w przypadku nieprawidłowego zakończenia, takiego jak zgłoszenie wyjątku C++).

Użyj w C++

W języku C++ struktura programowania try {/* ... */} catch {/* ... */} może (w zależności od platformy hosta) opierać się na sygnalizacji. Aby przechwycić sygnały przetłumaczone na wyjątki C++, na niektórych platformach mogą być potrzebne specjalne przełączniki kompilatora, takie jak -fnon-call-exceptions dla GCC i Intel C Compiler.

Przykład

 
 
 
 
 
 



   

	  0


    #include  <stdio.h>  #include  <stdlib.h>  #include  <string.h>  #include  <unistd.h>  #include  <sys/wait.h>  #include  <signal.h>  #define NUMCHLDS 10  void  sigchld_handler  (  int  ,  siginfo_t  *  ,  pustka  *  );  sig_atomic_t  nexitedchlds  =  ;  int  main  (  int  argc  ,  char  * 


	  

	 0  
	

	  

	  

	    argv  [])  {  struct  sigaction  akt  ;  memset  (  &  act  ,  ,  sizeof  (  struct  sigaction  ));  sigemptyset  (  &  akt  .  sa_mask  );  działać  .  sa_sigaction  =  sigchld_handler  ;  działać  .  sa_flags  =  SA_SIGINFO  ;  if  (  -1  ==  sigakcja  (   
	
		
		
	

	    0    
	
		
		
			 0
                                
 SIGCHLD  ,  &  akt  ,  NULL  ))  {  perror  (  "sigaction()"  );  wyjście  (  EXIT_FAILURE  );  }  for  (  int  i  =  ;  i  <  NUMCHLDS  ;  i  ++  )  {  switch  (  fork  ())  {  case  :  /*  * Starsze implementacje systemu operacyjnego, które nie implementują poprawnie 



				 
				
			 
				  
				
				
			
				 * struktura siginfo obetnie kod wyjścia  *, maskując go wartością 0xFF.  */  powrót  1234567890  ;  /* NOTREACHED */  case  -1  :  write  (  STDERR_FILENO  ,  "fork ERROR!"  ,  11  );  wyjście  (  EXIT_FAILURE  );  /* NOTREACHED */  default  :  printf  (  "Dziecko utworzone  \n 
		
	


	 
	
		   
			
		
			
	
        
	 0



     


	  "  );  }  }  while  (  1  )  {  if  (  nexitedchlds  <  NUMCHLDS  )  pauza  ();  else  wyjdź  (  EXIT_SUCCESS  );  }  /* NOTREACHED */  return  ;  }  void  sigchld_handler  (  int  signo  ,  siginfo_t  *  sinfo  ,  void  *  context  )  {  pid_t  proc 
	
	       0
	
		
		

		




		 ;  while  ((  proc  =  waitpid  (  -1  ,  NULL  ,  WNOHANG  ))  >  )  {  /* główny wątek sygnału */  nexitedchlds  ++  ;  /*  * uwaga: printf() nie jest bezpieczne dla sygnału!  * nie używaj go w module obsługi sygnału.  * si_code to pełny 32-bitowy kod wyjścia dziecka (zobacz także waitid()).  */  printf  (  "sinfo->si_pid = %ld  \n  proc = %ld  \n 
				   
	
 kod wyjścia %d powód wyjścia %d  \n  "  ,  (  long  )  sinfo  ->  si_pid  ,  (  long  )  proc  ,  sinfo  ->  si_status  ,  sinfo  ->  si_code  );  }  } 

Linki zewnętrzne