Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 线程在循环中等待信号_C_Multithreading_Gcc_Pthreads - Fatal编程技术网

C 线程在循环中等待信号

C 线程在循环中等待信号,c,multithreading,gcc,pthreads,C,Multithreading,Gcc,Pthreads,我是C语言的新手。我想创建一个程序,其中有两个线程将在循环中发送信号(SIGUSR1和sigusr2),还有四个线程将等待并处理这些信号 我知道发送我需要做的信号:kill(getpid,SIGUSR1)

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

我知道发送我需要做的信号:
kill(getpid,SIGUSR1)
我是否可以让其他线程也检查信号类型(不停止信号到达其他线程)

谢谢


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


使用
pthread\u kill()
时,我需要指定线程id(我正在尝试不这样做)。

更新:这个答案可能部分没有用。您应该使用
pthread\u kill
向特定线程发送信号。不过,我会留着它,以防有人在里面发现什么


在Linux上,线程不能用
kill
来处理,因为
kill
会将信号发送给任何不阻塞信号的随机线程

相反,您需要系统调用,它以特定线程为目标。哪根线?你可以通过系统调用找到答案

不幸的是,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);
}

我真的不建议使用SIGUSR信号进行线程同步。如果您希望pthread等待信号,我会查看
pthread\u cond\u signal

的手册页,谢谢您的回答。但是我是否指定了要向其发送信号的线程?我怎么知道哪根线会抓住它?还有,如何在循环中发送信号?@Mike:在所需线程中使用
gettid
!不过,我不确定您是否可以获得不同线程的线程id。您可以枚举
/proc//task/
,并排除您自己的线程id,以查看其他线程id是什么。或者让每个新线程发回一个信号(检查文档,您可以在siginfo部分添加数据)。创建线程时只保留线程的ID是另一个明显的选择。@PaulGriffiths:如何?我不认为有人会以任何方式报告它们。@PaulGriffiths:(除非您放弃pthreads并直接使用
clone()
directly.phrr。)是否有理由使用信号(看起来像是同步问题)?“随机进程”是什么意思?您可以为每个线程设置信号掩码,只允许信号到达某些线程,然后使用
kill
让内核选择任意随机线程来接收信号。或者您可以主动枚举所有线程,使用随机数生成器从中进行选择,并发送定向信号。@KerrekSB,我可以同时向两个进程发送信号吗?哪个进程空闲,哪个进程将处理该信号?或者我可以创建几个属于同一组的进程并将信号发送给整个组吗?您可以向整个进程发送信号,并且只有一个线程接收信号,该线程不能阻塞线程,并且是随机选择的。保证信号最多发送一次。
// 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);