6

特定のシグナルをブロックし、同じセット内の他のシグナルのブロックを解除する方法はありますか? 私はそれを理解していないようです!

sigset_t set;
sigemptyset(&set);

sigaddset(&set, SIGUSR1);
// Block signal SIGUSR1 in this thread
pthread_sigmask(SIG_BLOCK, &set, NULL);
sigaddset(&set, SIGALRM);
// Listen to signal SIGUSR2
pthread_sigmask(SIG_UNBLOCK, &set, NULL);


pthread_t printer_thread1, printer_thread2;
pthread_create(&printer_thread1, NULL, print, (void *)&f1);
pthread_create(&printer_thread2, NULL, print, (void *)&f2);

bool tl = true;
while(1)
{
    if(tl)
    {
        // thread1 does something
        kill(pid, SIGUSR1);
        // main thread waits for SIGALRM
        sigwait(&set, &sig);
        tl = !tl;
    }
    else
    {
        // thread2 does something
        kill(pid, SIGUSR2);
        // main thread waits for SIGALRM
        sigwait(&set, &sig);
        tl = !tl;
    }
}

Mutex、セマフォなどのシグナルのみを使用することは許可されていません。

誰か助けてくれませんか?:)

4

2 に答える 2

11

特定のシグナルをブロックし、同じセット内の他のシグナルのブロックを解除する方法はありますか?

ではpthread_sigmask、次のいずれかを選択できます。

  • 定数を使用して、シグナルのセットをブロックされたシグナルのセットに追加します。SIG_BLOCK
  • 定数を使用して、ブロックされたシグナルのセットからシグナルのセットを削除しますSIG_UNBLOCK
  • 定数を使用して、ブロックするシグナルのセットを定義しますSIG_SET

言い換えれば、スレッドに対して現在ブロックされているシグナルのセットがあり、上記のように一度に 1 つの操作でそれを変更できます。

重要な点は、新しく作成されたスレッドは作成中のスレッドのシグナル マスクを継承するため、新しいスレッドを作成する直前に、または新しいスレッドが実行される関数内で都合のよいときにマスクを設定できることです。

あなたの例については、各スレッドが単一のスレッドによってキャッチされるシグナルを送信できるように、ブロック と 、ブロック と、およびメインスレッド ブロックprinter_thread1とを使用しようとしていると思います ( のコードなしでそして、あなたの例であなたの意図が何であるかを確実に知ることは不可能です)。SIGUSR2SIGALRMprinter_thread2SIGUSR1SIGALRMSIGUSR1SIGUSR2printf1f2

次のコードでそれを達成できるはずです。

sigset_t set;
pthread_t printer_thread1, printer_thread2;


// Block signal SIGUSR1 & SIGALRM in printer_thread1
sigemptyset(&set);
sigaddset(&set, SIGUSR1);
sigaddset(&set, SIGALRM);
pthread_sigmask(SIG_SET, &set, NULL);
pthread_create(&printer_thread1, NULL, print, (void *)&f1);

// Block signal SIGUSR2 & SIGALRM in printer_thread2
sigaddset(&set, SIGUSR2);
sigaddset(&set, SIGALRM);
pthread_sigmask(SIG_SET, &set, NULL);
pthread_create(&printer_thread2, NULL, print, (void *)&f2);

// Block signal SIGUSR1 & SIGUSR2 in the main thread
sigemptyset(&set);
sigaddset(&set, SIGUSR1);
sigaddset(&set, SIGUSR2);
// Listen to signal SIGALRM
pthread_sigmask(SIG_SET, &set, NULL);


bool tl = true;
while(1)
{
    if(tl)
    {
        // thread1 does something
        kill(pid, SIGUSR1);
        // main thread waits for SIGALRM
        sigwait(&set, &sig);
        tl = !tl;
    }
    else
    {
        // thread2 does something
        kill(pid, SIGUSR2);
        // main thread waits for SIGALRM
        sigwait(&set, &sig);
        tl = !tl;
    }
}

次のマニュアル ページを参照してください。

詳細については。

于 2012-10-29T01:46:05.933 に答える
2

ここでやりたいことは

// Block signal SIGUSR1 in this thread
sigemptyset(&set);
sigaddset(&set, SIGUSR1);
pthread_sigmask(SIG_BLOCK, &set, NULL);

// Listen to signal SIGALRM
sigemptyset(&set);
sigaddset(&set, SIGALRM);
pthread_sigmask(SIG_UNBLOCK, &set, NULL);

セットは、何をブロックまたはブロック解除するかを伝えるためにのみ使用されます。コマンドに渡された後は、自由にリセットして、別のシグナル マスクを作成できます。sigemptyset をスキップすると、セットには SIGUSR1 が含まれたままになり、その後再びブロックが解除されます。ええと、少なくともそれが機能する方法だと思います-シグナルを使用してから長い時間が経ちました。

于 2012-10-29T01:17:00.470 に答える