2012-10-29 83 views
5

有没有办法阻止某些信号并解除同一组中的其他信号? 我只是似乎没有得到我的头!posix线程阻塞信号并解除阻塞

一个例子

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; 
    } 
} 

我不允许使用Mutexs,信号灯等只有信号。

有人可以帮忙吗? :)

+0

你不是第一次封锁SIGUSR1吗?在UNBLOCK时,该集合包含SIGUSR1和SIGALRM。 – amaurea

回答

9

有没有办法阻止某些信号并取消阻止其他信号在 同一组?

随着pthread_sigmask,你可以选择是:

  • 添加一组信号到设定阻断信号,使用常量SIG_BLOCK
  • 删除一组信号到设定的封锁信号,使用恒定SIG_UNBLOCK
  • 定义所述一组信号被阻止,使用恒定SIG_SET

换句话说,线程有一组当前阻塞的信号,您可以按照上面的指定进行修改,一次只进行一个操作。

重要的一点是新创建的线程会继承创建线程的信号掩码,因此您可以在创建它之前或在新线程运行的函数中设置新线程的掩码。

关于你的榜样,我想,你想有printer_thread1SIGUSR2SIGALRM,并有printer_thread2SIGUSR1SIGALRM,并有主线程块SIGUSR1SIGUSR2,使每个线程都可以发出一个信号,将被单线程捕获(没有print,f1f2的代码,不可能知道你的例子中你的意图是什么)。

您应该能够通过下面的代码来实现这一目标:

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; 
    } 
} 

看到这些手册页:

进一步的细节。

+0

谢谢,这是有道理的,但它实际上不适用于打印机线程。但我明白现在面具如何工作。 – Max

1

我想你想在这里做的是

// 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,随后将再次解除阻塞。那么,我认为至少它是如何工作的 - 从我使用信号开始已经很长时间了。