在信号句柄中使用 pthread_cond_wait 的 Pthread 被阻塞

Posted

技术标签:

【中文标题】在信号句柄中使用 pthread_cond_wait 的 Pthread 被阻塞【英文标题】:Pthread using pthread_cond_wait inside signal handle blocked 【发布时间】:2017-12-20 04:43:42 【问题描述】:

我想编写一个程序,它可以在没有主线程的情况下停止(挂起)所有其他 pthread,我使用pthread_kill 向目标线程发送信号以调用其信号处理程序,该处理程序可以自行阻塞。但我被卡住了。下面是代码:

#include <iostream>
#include <signal.h> 
#include <pthread.h>
#include <unistd.h>
#include <cassert>

using namespace std;

pthread_mutex_t _mutex;
pthread_cond_t cond;

void cur_thread_wait(int sig)

    cout << pthread_self() << endl;

//  pthread_mutex_lock(&_mutex);
    pthread_cond_wait(&cond, &_mutex);  
//  pthread_mutex_unlock(&_mutex);


void signal_all()

    pthread_cond_broadcast(&cond);


void *print(void *)

    pthread_detach(pthread_self());
    for (int i = 0; i < 100; i ++) 
        cout << dec << i << endl;
    
    return nullptr;



int main(int argc, char *argv[]) 

    pthread_mutex_init(&_mutex, nullptr);
    pthread_cond_init(&cond, nullptr);

    signal(SIGUSR1, cur_thread_wait);

    pthread_t pid1, pid2, pid3;
    pthread_create(&pid1, nullptr, print, nullptr);
    pthread_create(&pid2, nullptr, print, nullptr);
    pthread_create(&pid3, nullptr, print, nullptr);

//  usleep(400);

    pthread_kill(pid1, SIGUSR1);
    pthread_kill(pid2, SIGUSR1);
    pthread_kill(pid3, SIGUSR1);

    signal_all();


    pthread_exit(nullptr);

事实上,我认为真的没有必要创建mutex(这是真的吗?)...我是linux 编程的新手。我该如何解决这个问题?谢谢。

【问题讨论】:

这是坏的 - 你不应该在信号处理程序中阻塞! 【参考方案1】:

确实需要在调用pthread_cond_wait 之前锁定互斥锁;它期望它被锁定,它解锁它,等待条件变量被断言,然后在返回给你之前重新锁定它。

来自pthread_cond_wait(3p)

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

pthread_cond_timedwait()pthread_cond_wait() 函数应阻塞条件变量。应用程序应确保调用这些函数时 mutex 被调用线程锁定;否则,将导致错误(对于PTHREAD_MUTEX_ERRORCHECK 和健壮的互斥锁)或未定义的行为(对于其他互斥锁)。

【讨论】:

谢谢。我发现我的错...如果我把usleep 放在signal_all 之前,程序就会正确。此外你是对的,因为mutex 是必要的。 感谢您的更新!您还可以在大多数系统(包括 Linux)上使用 sched_yield 他不应该在信号处理程序中进行阻塞调用。此外,由于问题标记为 C++,因此杀死和取消 posix 线程可能会导致 C++ 出现问题。参见例如skaark.wordpress.com/2010/08/26/…

以上是关于在信号句柄中使用 pthread_cond_wait 的 Pthread 被阻塞的主要内容,如果未能解决你的问题,请参考以下文章

win32 相关同步api

win32 相关同步api

waitformultipleobjects 具有未知数量的句柄

RTOS二值信号量使用流程

RTOS计数型信号量的使用流程

Windows 句柄等到所有引用都被释放