1

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

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

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

谢谢。


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

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

4

2 回答 2

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,它也构成了/proc/<pid>/task/Linux 中的目录。

最后,您需要能够等待信号到达。为此,您可以使用 or 阻塞线程中的信号,pthread_sigmask然后使用sigwaitinfoorsigtimedwait

// 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);
于 2013-09-24T21:51:12.073 回答
0

我真的不建议使用 SIGUSR 信号进行线程同步。如果您希望 pthreads 等待信号,我会查看手册页pthread_cond_signal

于 2013-09-25T02:26:08.463 回答