C语言 在 C 中向 pthread 发送和捕获信号

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4208929/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 07:06:07  来源:igfitidea点击:

Send and catch signals to pthreads in C

cmultithreadingprocesspthreads

提问by gvalero87

I know how to send signals to child process in C using the kill(pid_t pid, int sig)function. What about sending signals to threads? is it possible?. If so, how to catch signals on the "child" thread. For example, if the main thread sends me a terminate signal, how can I in the other thread catch it.

我知道如何使用该kill(pid_t pid, int sig)函数向 C 中的子进程发送信号。向线程发送信号怎么样?是否可以?。如果是这样,如何在“子”线程上捕获信号。例如,如果主线程向我发送终止信号,我如何在另一个线程中捕获它。

采纳答案by Blagovest Buyukliev

With POSIX threads, you have the functions pthread_cond_waitand pthread_cond_signal.

使用 POSIX 线程,您可以使用函数pthread_cond_waitpthread_cond_signal.

int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex)
int pthread_cond_signal(pthread_cond_t *cond)

The signaled thread should block on a pthread_cond_waitcall until another thread sends a signal using pthread_cond_signal, with the same condition variable.

发出信号的线程应该在pthread_cond_wait调用上阻塞,直到另一个线程使用pthread_cond_signal相同的条件变量发送信号。

Considering the analogy with signals delivered to processes, this is a bit different because the signaled thread has already suspended its execution waiting for a signal, unlike a process that simply gets interrupted and goes on.

考虑到将信号传递给进程的类比,这有点不同,因为发出信号的线程已经挂起其执行等待信号,这与简单地被中断并继续运行的进程不同。

回答by Jonathan Leffler

Signals are sent to a process as a whole. Each signal sent to the process is received by a single thread (on behalf of the whole program). There are per-thread signal masks which influence whether a particular thread is eligible to handle a particular signal.

信号作为一个整体发送到一个进程。发送到进程的每个信号都由单个线程(代表整个程序)接收。每个线程的信号掩码会影响特定线程是否有资格处理特定信号。

So, you need a signal handler - possibly in just one thread. Note that there are limits on what you're supposed to do in a thread's signal handler, though. Be wary of stepping far outside the promises made by the standard (which are minimal).

所以,你需要一个信号处理程序——可能只在一个线程中。请注意,您应该在线程的信号处理程序中执行的操作是有限制的。小心远离标准做出的承诺(这是最小的)。

However, the pthread_kill()function can be used to send signals to other threads as long as the current thread can identify (has access to the thread ID values (pthread_t) that identify) the threads that are still executing within the process. You might decide to relay the signal to the other threads using a different signal number from the one originally caught (so one thread receives the external signal, but many threads receive the internal signal). Or you might use another Pthread synchronization or communication primitive instead of signals.

但是,该pthread_kill()函数可用于向其他线程发送信号,只要当前线程可以识别(可以访问用于识别的线程 ID 值 ( pthread_t))仍在进程内执行的线程。您可能决定使用与最初捕获的信号编号不同的信号编号将信号中继到其他线程(因此一个线程接收外部信号,但许多线程接收内部信号)。或者您可以使用另一个 Pthread 同步或通信原语而不是信号。

回答by Adam Rosenfield

Signals do not have thread affinity. They are handled completely asynchronously. When you specify a signal handler with signal(2)or sigaction(2), it's a global signal handler. When a signal is raised, the signal handler runs on top of the stack of whatever thread happens to be running at the time, and you can't control that.

信号没有线程关联。它们是完全异步处理的。当您使用signal(2)或指定信号处理程序时sigaction(2),它是一个全局信号处理程序。当发出信号时,信号处理程序运行在当时正在运行的任何线程的堆栈顶部,您无法控制它。

It sounds like you want some other sort of interthread communication. The simplest way to do this is with a volatileshared variable:

听起来您想要某种其他类型的线程间通信。最简单的方法是使用volatile共享变量:

volatile bool should_terminate = false;

void ChildThread()
{
    while(!should_terminate)
    {
        // do stuff
    }
}

void MainThread()
{
    // To terminate child thread:
    should_terminate = true;
}

If you need stronger concurrency control, look into mutexes, condition variables, and semaphores.

如果您需要更强的并发控制,请查看互斥锁、条件变量和信号量。

回答by bot403

I'm not sure this is possible as it is platform and implementation dependant and I highly suggest you don't use signals to communicate between threads. Sometimes only a specific thread will receive signals and sometimes all threads receive signals.

我不确定这是否可行,因为它取决于平台和实现,我强烈建议您不要使用信号在线程之间进行通信。有时只有特定线程会收到信号,有时所有线程都会收到信号。

Better thread communucation mechanisms exist like queues, semaphores, and locks.

存在更好的线程通信机制,如队列、信号量和锁。