Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.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
pthread_cond_wait在签名\u handler()后返回?_C_Linux_Multithreading_Synchronization_Conditional Statements - Fatal编程技术网

pthread_cond_wait在签名\u handler()后返回?

pthread_cond_wait在签名\u handler()后返回?,c,linux,multithreading,synchronization,conditional-statements,C,Linux,Multithreading,Synchronization,Conditional Statements,同事们 如果我向停留在pthread_cond_wait()上的线程发送SIGINT信号,当sign_handler()返回时,pthread_cond_wait()也会返回吗 如果没有,是否有任何方法使pthread_cond_wait()返回 如果我向停留在pthread_cond_wait()上的线程发送SIGINT信号,当sign_handler()返回时,pthread_cond_wait()也会返回吗 没有 如果没有,是否有任何方法使pthread_cond_wait()返回 不,你

同事们

如果我向停留在pthread_cond_wait()上的线程发送SIGINT信号,当sign_handler()返回时,pthread_cond_wait()也会返回吗

如果没有,是否有任何方法使pthread_cond_wait()返回

如果我向停留在pthread_cond_wait()上的线程发送SIGINT信号,当sign_handler()返回时,pthread_cond_wait()也会返回吗

没有

如果没有,是否有任何方法使pthread_cond_wait()返回

不,你试图使用错误的工具来解决任何潜在的问题

(从技术上讲,
pthread\u cond\u timedwait()
允许在信号传递中断时返回,但它不会返回,至少在运行内核5.3.0的x86-64上使用GNU glibc 2.27时是这样。是的,我检查过了。)

我如何解决我的问题

让我们假设条件变量是您用例的最佳选项。(不过,这只是一个猜测;您没有告诉我们您试图解决的真正问题,只是告诉我们您选择的解决方案如何不起作用。)

然后,推荐的解决方案是使用helper线程捕获信号,如SIGINT、using或sigtimedwait()。然后,该助手线程可以在相关条件变量上设置一个特定的退出所需的
volatile sig\u atomic\u标记和
pthread\u cond\u signal()
pthread\u cond\u broadcast()
,让它们知道发生了什么重要的事情。那些等待条件变量的人显然应该首先检查helper标志;如果设置了,则假设这是唤醒信号的来源。通常我将这些标志命名为“需要退出”或类似标志

这种信号处理辅助线程的关键是需要在所有线程(包括处理辅助线程本身)中阻塞信号。最好在创建任何其他线程之前在主线程中执行此操作,因为这样创建的线程将继承相同的信号掩码

siginfo_t结构包含各种有用的信息。最有用的可能是
.si_pid
字段,它告诉哪个进程(或
0
if内核)发送了信号。这样,如果出于内部目的使用say
SIGRTMIN+0
SIGRTMAX-0
信号,则可以忽略它们,除非它们来自进程本身(其他线程,
.si_pid==getpid()

线程取消(延迟,在取消点;pthread_cond_wait()是取消点)是另一个选项。可以使用pthread_cleanup_push()设置/添加要在线程取消时运行的函数。这基本上是强制终止目标线程,但它可以运行在终止之前设置的任何清理函数。您还可以使用pthread_cleanup_pop()解除任何清理函数的作用——一个参数指定是运行并丢弃清理函数,还是仅丢弃清理函数。但是,当被取消时,线程总是死亡


请使用
pthread\u attr\u t
将堆栈大小限制为2的合理幂。如果堆栈上没有任何大型数组或结构(局部变量),那么

#include <limits.h>

#ifndef  THREAD_STACK_SIZE
#define  THREAD_STACK_SIZE  (4 * PTHREAD_STACK_MIN)
#endif
对于堆栈大小和阻塞所有线程中的某些信号(通过在创建其他线程的线程中首先阻塞它们;它们将继承信号掩码),应该可以正常工作

除了不能被阻止、捕获或忽略的
SIGKILL
SIGSTOP
之外,您可以向被阻止的掩码添加任何其他信号

pthread\u attr\u t
pthread\u create()
的第二个参数只是设置(或属性)的集合,如配置;pthread_create()调用不会“使用”它们。可以多次使用同一组属性。这一个只包含所需的堆栈大小。(它不包含堆栈本身,只包含所需的大小。)

默认的堆栈大小非常大,通常为8MIB,这意味着大量虚拟内存是为线程堆栈保留的,实际上没有什么好的理由。此外,它严重限制了进程可以创建的线程数

在许多方面,拥有用于信号处理的助手线程比实际的信号处理程序更容易,因为只有在信号处理程序中才能安全使用;而在helper线程中,您可以使用all

如果我向停留在pthread_cond_wait()上的线程发送SIGINT信号,当sign_handler()返回时,pthread_cond_wait()也会返回吗

没有

如果没有,是否有任何方法使pthread_cond_wait()返回

不,你试图使用错误的工具来解决任何潜在的问题

(从技术上讲,
pthread\u cond\u timedwait()
允许在信号传递中断时返回,但它不会返回,至少在运行内核5.3.0的x86-64上使用GNU glibc 2.27时是这样。是的,我检查过了。)

我如何解决我的问题

让我们假设条件变量是您用例的最佳选项。(不过,这只是一个猜测;您没有告诉我们您试图解决的真正问题,只是告诉我们您选择的解决方案如何不起作用。)

然后,推荐的解决方案是使用helper线程捕获信号,如SIGINT、using或sigtimedwait()。然后,该助手线程可以在相关条件变量上设置一个特定的退出所需的
volatile sig\u atomic\u标记和
pthread\u cond\u signal()
pthread\u cond\u broadcast()
,让它们知道发生了什么重要的事情。那些等待条件变量的人显然应该首先检查helper标志;如果设置了,则假设这是唤醒信号的来源。通常我将这些标志命名为“需要退出”或类似标志

这种信号处理辅助线程的关键是需要在所有线程(包括处理辅助线程本身)中阻塞信号。最好在创建任何其他线程之前在主线程中执行此操作,就像创建的thr一样
sigset_t        mask;
pthread_attr_t  attrs;
int             err;

/* Block SIGINT in this (and all created threads) */
sigemptyset(&mask);
sigaddset(&mask, SIGINT);
err = pthread_sigmask(SIG_BLOCK, &mask, NULL);
if (err) {
    fprintf(stderr, "Cannot block signals: %s.\n", strerror(err));
    return EXIT_FAILURE;
}

/* Create stack size attribute. */
pthread_attr_init(&attrs);
pthread_attr_setstacksize(&attrs, THREAD_STACK_SIZE);

/*
 * Create threads, use &attrs for the second parameter.
*/

/* Optional cleanup - it's a good idea to be careful. */
pthread_attr_destroy(&attrs);