线程在循环中等待信号

时间:2013-09-24 21:46:15

标签: c multithreading gcc pthreads

我是C的新手。我想创建一个程序,其中包含两个将在循环中发送信号(SIGUSR1和SIGNUSR2)的线程以及将等待这些信号并处理它们的四个线程。

我明白发送我需要做的信号:kill(getpid,SIGUSR1);但我如何创建四个等待信号的线程?信号被注册到特定功能。四个线程如何等待相同的信号?

我是否可以让其他线程检查信号类型(不停止信号到达其他线程)?

感谢。


更新:
我正在尝试让四个线程等待信号,当两个线程发送信号时,线程不知道哪个线程会捕获信号。我不想指定将接收信号的线程ID。

使用pthread_kill()时,我需要指定线程ID(我不想这样做)。

2 个答案:

答案 0 :(得分:2)

更新:这个答案可能部分无用。您应该使用pthread_kill将信号发送到特定线程。不过,如果有人发现了某些东西,我会留下它。


在Linux上,无法使用kill处理线程,因为kill会将信号发送到任何未阻塞信号的随机线程。

相反,您需要tgkill系统调用,该调用以特定线程为目标。哪个帖子?您可以通过系统调用gettid找到答案。

不幸的是,glibc没有为这两个系统调用提供包装器。没问题,你可以自己写一下:

#include <signal.h>
#include <sys/syscall.h>
#include <sys/types.h>

pid_t gettid()
{
    return syscall(SYS_gettid);
}

int tgkill(int sig, pid_t pgid, pid_t tid)
{
    return syscall(SYS_tkill, sig, pgid, tid);
}

tgkill的第一个参数是kill的信号。第二个是线程组ID ,它与您的进程的进程ID 相同(可通过getpid获得)。最后一个参数是内核线程id,它是使用gettid获得的,它也构成了Linux上/proc/<pid>/task/中的目录。

最后,您需要等待信号到达。您可以通过使用pthread_sigmask阻止线程中的信号,然后使用sigwaitinfo or sigtimedwait

来执行此操作
// block signal
sigset_t newset, oldset;
sigemptyset(&nweset);
sigaddset(&newset, SIGUSR1);
pthread_sigmask(SIG_BLOCK, &newset, &oldset);

// wait
sigwaitinfo(&newset, NULL);

// restore previous signal mask
pthread_sigmast(SIG_SETMASK, &oldset, NULL);

答案 1 :(得分:0)

我真的不建议使用SIGUSR信号进行线程同步。如果你想让pthreads等待信号,我会查看pthread_cond_signal

的手册页