我是C的新手。我想创建一个程序,其中包含两个将在循环中发送信号(SIGUSR1和SIGNUSR2)的线程以及将等待这些信号并处理它们的四个线程。
我明白发送我需要做的信号:kill(getpid,SIGUSR1);
但我如何创建四个等待信号的线程?信号被注册到特定功能。四个线程如何等待相同的信号?
我是否可以让其他线程检查信号类型(不停止信号到达其他线程)?
感谢。
更新:
我正在尝试让四个线程等待信号,当两个线程发送信号时,线程不知道哪个线程会捕获信号。我不想指定将接收信号的线程ID。
使用pthread_kill()
时,我需要指定线程ID(我不想这样做)。
答案 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