信号:signalおよびsigaction

4121 ワード

プログラムはsignalライブラリ関数を使用して信号を処理することができ、以下のように定義される.
#include 
void  (*signal(int sig,void (*func)(int)))(int);

ここで、パラメータsigは、取得または無視の準備をする信号を与え、信号を受信した後に呼び出す必要がある関数は、パラメータfuncによって与えられる.信号処理関数は、以下の2つの特殊値を用いてもよい
SIG_IGN         
SIG_DFL           

現在多く使われているのはsignalではなくsigactionです.次のように定義します.
#include
int sigaction(int sig,const struct sigaction *act ,struct sigaction *oact)

Sigactionの構造定義もファイルsignal.h中.彼の役割は,パラメータsigによって定められた信号を受信した後に取るべき行動を定義することである.構造には、少なくとも次のメンバーが含まれている必要があります.
void (*)(int)sa_handler     /*function,SIG_DFL OR SIG_IGN
sigset_t sa_mask        /*signals to block in sa_handler
int sa_flags            /*signal action modifiers

Sigaction関数は、信号sigに関連付けられた動作を設定します.oactが空のポインタでない場合、sigactionは、信号に対する元の動作を指向する位置に書く.actが空のポインタである場合、sigaction関数は他の設定を必要としません.そうしないと、このパラメータに指定された信号に対する動作が設定されます.signal関数と同様に、sigaction関数が成功した場合は0を返し、失敗した場合は-1を返します.信号が無効であるか、キャプチャまたは無視が許されない信号をキャプチャまたは無視すると、エラー変数errnoがEINVALに設定されます.パラメータactが考えているsigaction構造ではsa_handlerは関数ポインタで、signalのfuncと同様にSIG_に設定できます.IGNとSIG_DFL. Sigactionのメンバーのうち、sa_maskは、シールドされる信号を保存する信号セットを作成しました.信号セットのタイプ名はsigset_t、および一連の処理信号セットの関数:
#include 
int sigaddset(sigset_t *set,int signo);     /*       
int sigemptyset(sigset_t *set);         /*        
int sigfillset(sigset_t *set);          /*               
int sigdelset(sigset_t *set,int signo);     /*       
int sigismember(sigset_t *set ,int signo);  /*          
int sigprocmask(int how, const sigset_t *set ,sigset_t *oset);

最後に、そのsigprocmask関数は複雑であり、howパラメータに基づいてプロセスの信号シールドワードを修正し、新しい信号シールドワードはパラメータset(空でない場合)によって与えられ、元のものはosetに保存される.setが空の場合、この関数の唯一の目的は現在の信号シールドワードをosetに保存することである.howの集中値は以下の表から与えられる.
SIG_BLOCK   |      set             
SIG_SETMASK |              set    
SIG_UNBLOCK |              set    

ここでの信号シールドワードについて簡単に説明すると、ここでの信号シールドとは、信号が来たことを意味し、現在のプロセスには伝達されないが、信号はまだ処理対象の状態にとどまり、unblockになると、信号は再び到着する.プログラムは、関数sigpendingを呼び出すことによって、ブロックされた信号の中で処理対象の状態にとどまっているものを確認することができる.
int sigpending(sigset_t *set);

この関数は、パラメータsetで指定された信号セットに、処理対象の状態にとどまる信号を書き込む.プログラムが信号を処理する必要がある場合、信号処理関数の呼び出し時間を制御する必要がある場合に使用します.Sigactionにはpause関数をよりよく実現できる関数があります.
int sigsuspend (const sigset_t *sigmask);

この関数は、プロセスのシールドワードをsigmaskが与えた信号セットに置き換え、プログラムの実行を停止します.1つの信号をキャプチャした後、まず信号処理プログラムを実行し、sigsuspendから戻り、最後に信号シールドワードをsigsuspendを呼び出す前の値に復元する.受信した信号がプログラムを終了するとsuspendは返されず、プログラムを終了しないと-1が返され、errnoがEINTRに設定されます.