7

私は小さなコードを書きました。このコードは、最初に {SIGSEGV} をブロックし、次に SIGRTMIN を同じセットに追加します。最終的なシグナル セットは {SIGSEGV,SIGRTMIN} です。したがって、SIG_UNBLOCK を使用する場合、私の理解では、最初に SIGRTMIN のブロックを解除し、次に SIG_UNBLOCK を呼び出すと、SIGSEGV のブロックを解除する必要があります。

つまり、1) {SIGSEGV,SIGRTMIN} 2) SIG_UNBLOCK = SIGRTMIN のブロックを解除します。3) SIG_UNBLOCK を再度呼び出します = SIGSEGV のブロックを解除します。プロセスに SIGRTMIN のみを与えているため、2 回目のブロック解除は SIGRTMIN でプロセスを停止する必要があります。そうではありません。助けてください。 注意: sigprocmask( ) に関する他の質問の回答へのリンクを提供しないでください。私はそれらを見ましたが、私の質問を明確にしていません。

enter code here
#include <signal.h>
#include <unistd.h>
#include <stdio.h>

int main()
{
 sigset_t old_set,new_set;
 sigemptyset(&old_set);
 sigemptyset(&new_set);

 if(sigaddset(&old_set,SIGSEGV)==0)
 {
   printf("sigaddset successfully added for SIGSEGV\n");
 }
 sigprocmask(SIG_BLOCK,&old_set,NULL); // SIGSEGV signal is masked
 kill(0,SIGSEGV);


 //*****************************************************************

 if(sigaddset(&new_set,SIGRTMIN)==0)
 {
  printf("sigaddset successfully added for SIGRTMIN\n");
 }
  sigprocmask(SIG_BLOCK,&new_set,&old_set); // SIGRTMIN signal is masked
 kill(0,SIGSEGV);

 //****************** Unblock one signal at a time ******************

 sigprocmask(SIG_UNBLOCK,&new_set,&old_set); // SIGRTMIN signal is unmasked
 sigprocmask(SIG_UNBLOCK,&new_set,&old_set); // SIGSEGV signal is unmasked

}

Output:
 [root@dhcppc0 signals]# ./a.out
  sigaddset successfully added for SIGSEGV
  sigaddset successfully added for SIGRTMIN
  (Note:SIGSEGV is not received even after sigprocmask(SIG_UNBLOCK,&new_set,&old_set); a second time)
4

2 に答える 2

13

あなたの前提は間違っています。の 1 回の呼び出しで、セット全体がブロックおよびブロック解除されsigprocmaskます。

また、通常、ブロックしたいすべてのシグナルを含むセットを作成し、 でそれらすべてをブロックしようとしますsigprocmask(SIG_BLOCK, pointer_to_sigset);

ただし、コードは実際には SIGSEGV のブロックを解除しません。これは、スニペットが不必要に長くなるため、エラー処理なしで書くものです。ただし、すべての関数でエラーを確認してください。可能性のあるエラーのリストは、man ページで提供されています。

/* ... */
sigset_t signal_set; /* We don't need oldset in this program. You can add it,
                        but it's best to use different sigsets for the second
                        and third argument of sigprocmask. */
sigemptyset(&signal_set);

sigaddset(&signal_set, SIGSEGV);
sigaddset(&signal_set, SIGRTMIN);

/* now signal_set == {SIGSEGV, SIGRTMIN} */

sigprocmask(SIG_BLOCK, &signal_set, NULL): /* As i said, we don't bother with the 
                                              oldset argument. */

kill(0,SIGSEGV);  
kill(0,SIGSEGV);  /* SIGSEGV is not a realtime signal, so we can send it twice, but
                     it will be recieved just once */

sigprocmask(SIG_UNBLOCK, &signal_set, NULL); /* Again, don't bother with oldset */

/* SIGSEGV will be received here */

もちろん、シグナルのブロックを別々のセットの 2 つの操作に分割することもできます。メカニズムは次のように機能します。ブロックされたシグナルのセットがあり、oldset 引数を指定すると、oldset を置き換えます。でそのセットに追加しSIG_BLOCKたり、 でそのセットから削除したり、関数の引数をSIG_UNBLOCK使用してセット全体を好みに合わせて変更したりできます。SIG_SETMASKsigprocmask

于 2011-03-13T10:53:09.300 に答える
0

kubi が指摘したように: これが変更されたコードです。問題は、old_set と new_set をめちゃくちゃにしてしまったことです。SIGSEGV はブロック解除されていない old_set に追加されたため、セグメンテーション違反 (SIGSEGV シグナル) を受信しませんでした。クビのおかげです。

enter code here
#include <signal.h>
#include <unistd.h>
#include <stdio.h>

int main()
{
 sigset_t old_set,new_set;
 sigemptyset(&old_set);
 sigemptyset(&new_set);

 if(sigaddset(&old_set,SIGSEGV)==0)
 {
  printf("sigaddset successfully added for SIGSEGV\n");
 }
 sigprocmask(SIG_BLOCK,&new_set,&old_set); // SIGSEGV signal is masked
 kill(0,SIGSEGV);


//*****************************************************************

if(sigaddset(&new_set,SIGRTMIN)==0)
{
  printf("sigaddset successfully added for SIGRTMIN\n");
}
if(sigprocmask(SIG_BLOCK,&new_set,&old_set)==-1) // SIGRTMIN signal is masked
{
  perror("sigprocmask");
}
kill(0,SIGSEGV);


//****************** Unblock all signals  ******************

if(sigprocmask(SIG_UNBLOCK,&new_set,&old_set)==-1) // SIGRTMIN signal is unmasked
 {
  perror("sigprocmask");
 }
}
于 2011-03-13T11:58:27.463 に答える