posix线程阻塞信号并解除阻塞 [英] posix threads block signal and unblock

查看:171
本文介绍了posix线程阻塞信号并解除阻塞的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有一种方法可以阻止某些信号并取消阻止同一组中的其他信号? 我似乎没办法解决这个问题!

Is there a way to block certain signals and unblock other signals in the same set? I just dont seem to get my head around it!

一个例子

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,信号量等信号.

I am not allowed to use Mutexs, semaphores etc only signals.

有人可以帮忙吗? :)

Can someone help? :)

推荐答案

是否有一种方法可以阻止某些信号并取消阻止其他信号 同一套?

Is there a way to block certain signals and unblock other signals in the same set?

使用pthread_sigmask,您可以选择以下任一选项:

With pthread_sigmask, you can choose to either:

  • 使用常量SIG_BLOCK
  • 将一组信号添加到一组阻塞信号中
  • 使用常量SIG_UNBLOCK
  • 将一组信号删除为一组阻塞信号
  • 使用常量SIG_SET
  • 定义要阻止的信号集
  • add a set of signals to the set of blocked signals, using the constant SIG_BLOCK
  • remove a set of signals to the set of blocked signals, using the constant SIG_UNBLOCK
  • define the set of signals to be blocked, using the constant SIG_SET

换句话说,该线程有一组当前的阻塞信号,您可以按照上面指定的方式对其进行一次修改.

In other words, there's a current set of blocked signals for the thread, and you can modify it as specified above, one operation at a time.

重要的一点是,新创建的线程继承了创建线程的信号掩码,因此您可以在创建新线程之前设置它的掩码,也可以在方便时在新线程将要运行的函数中设置它.

The important point is that newly created threads inherit the signal mask of the creating thread, so you can set the mask of the new thread right before creating it, or in the function that the new thread will run, at your convenience.

关于您的示例,我想您正在尝试具有printer_thread1SIGUSR2SIGALRM,并且具有printer_thread2SIGUSR1SIGALRM,并且具有主线程块SIGUSR1SIGUSR2,以便每个线程可以发送将被单个线程捕获的信号(没有printf1f2的代码,因此无法确定您的意图是什么)例如).

Regarding your example, I suppose that you are trying to have printer_thread1 block SIGUSR2 and SIGALRM, and have printer_thread2 block SIGUSR1 and SIGALRM, and have the main thread block SIGUSR1 and SIGUSR2, so that each thread can send a signal that will be caught by a single thread (without the code of print, f1 and f2, it's impossible to know for sure what is your intent in your example).

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

You should be able to achieve that by the following code:

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

请参阅这些手册页:

  • pthread_sigmask
  • sigprocmask

了解更多详情.

这篇关于posix线程阻塞信号并解除阻塞的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆