Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.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_信号_C_Linux_Multithreading_Pthreads_Deadlock - Fatal编程技术网

导致死锁的pthread_cond_信号

导致死锁的pthread_cond_信号,c,linux,multithreading,pthreads,deadlock,C,Linux,Multithreading,Pthreads,Deadlock,我有一个程序,当其中一个线程调用pthread\u cond\u siganl(或广播)时会死锁。 该问题在主程序中100%可再现。我无法找出它的错误,因此提取了调用等待和信号的代码段。但是,死锁无法与提取的问题一起再现 在主程序上运行valgrind不会报告任何无效读/写或内存泄漏 我想知道调用pthread\u cond\u signal时死锁的可能原因是什么 下面是提取的代码片段 #include <pthread.h> #include <math.h> #inc

我有一个程序,当其中一个线程调用
pthread\u cond\u siganl
(或广播)时会死锁。 该问题在主程序中100%可再现。我无法找出它的错误,因此提取了调用等待和信号的代码段。但是,死锁无法与提取的问题一起再现

在主程序上运行
valgrind
不会报告任何无效读/写或内存泄漏

我想知道调用
pthread\u cond\u signal
时死锁的可能原因是什么

下面是提取的代码片段

#include <pthread.h>
#include <math.h>
#include <syscall.h>
#include <assert.h>
#include <stdlib.h>
#include <iostream>

using namespace std;

void Task() {
    cerr << syscall(SYS_gettid) << " In Task, sleeping..." << endl;
    sleep(5);
}

pthread_mutex_t lock;
pthread_cond_t cond;
bool doingTheTask= false;

void* func(void* ) { 
    pthread_mutex_lock(&lock);
    if (doingTheTask) {
        cerr << syscall(SYS_gettid) << " wait... " << endl;
        while ( doingTheTask) {//spurious wake-up
            cerr << syscall(SYS_gettid) << " waiting..." << endl ;
            pthread_cond_wait(&cond, &lock);
            cerr << syscall(SYS_gettid) << " woke up!!!" << endl ;
        }
    }
    else {
        cerr << syscall(SYS_gettid) << " My Turn to do the task..." << endl;
        assert( ! doingTheTask );
        doingTheTask= true;
        pthread_mutex_unlock(&lock);
        Task();
        cerr << syscall(SYS_gettid) << " Before trying to acquire lock" << endl;
        pthread_mutex_lock(&lock);
        cerr << syscall(SYS_gettid) << " After acquiring lock" << endl ;
        assert( doingTheTask );
        doingTheTask = false;
        cerr << syscall(SYS_gettid) << " Before broadcast" << endl;
        pthread_cond_broadcast(&cond);
        cerr << syscall(SYS_gettid) << " After broadcast" << endl;
    }
    pthread_mutex_unlock(&lock);
    return NULL;
}


int main() {
    pthread_mutex_init(&lock,NULL);
    pthread_cond_init(&cond,NULL);
    pthread_t thread[2];

    for ( int i = 0 ;  i < 2 ; i ++ ) {
        if (0 != pthread_create(&thread[i], NULL, func, NULL) ) {
            cerr << syscall(SYS_gettid) << " Error creating thread" << endl;
            exit(1);
        }
    } 

    for ( int i = 0 ;  i < 2 ; i ++ ) {
        pthread_join(thread[i],NULL);
    }
    pthread_mutex_destroy(&lock);
    pthread_cond_destroy(&cond);

    return 0;
}

这是一个类似的问题。但似乎问这个问题的人有记忆衰退。我没有内存损坏(表示
valgrind

这个问题在我测试的两台机器上是100%可重复的。(ArchLinux最新版本和Uubntu 10.04.3)

下面是主程序的示例输出。它再次显示线程在调用
pthread\u cond\u wait
pthread\u cond\u signal
之前阻塞。(第一列显示线程ID)

3967在任务中,正在睡觉。。。
3967轮到我做这项任务了。。。
3967在任务中,正在睡觉。。。
3973等等。。。
3973等待。。。
3976
3967在尝试获取锁之前
3967获得锁后
3967广播前

<>主程序是C++。但我使用C语言的部分,因此避免使用C++标签。

< P>当调用pthRead CONDIQueWATE(& COND,和COLD)时,锁将被释放,pHOLL将等待条件变量。当它获得条件变量上的信号时,它将获取锁并从pthread_cond_wait()中出来。在程序中,您在调用pthread_cond_broadcast(&cond)之前获得了互斥锁,因此pthread_cond_wait(&cond,&lock)在接收到信号时无法获取锁。我认为这就是僵局的原因。

愚蠢的错误。 在执行signal并等待之前,我正在销毁
mutex
condvar
。 要复制,只需在主函数中加入线程之前移动destroy函数


仍然令人惊讶的是,在我的两台机器上,这会产生100%一致(和错误)的行为。

(1)您确定您的程序死锁还是只是在循环运行?(2)从你发布的代码中,我推断出你的原始代码是C++而不是C?已经使用C++库可以分散你的问题。(3) 挑剔:在这种简单的情况下,不要对
mutex
cond
使用
init
destroy
函数。他们有静态初始值设定项。添加了一些输出@延斯古斯特1号。对我确信这是僵局。我提供了线程的死锁回溯跟踪。2.对的3.主程序并不简单,我使用的是RAII。因此我认为我们无法帮助您获得您提供的信息。您的软件环境似乎比您向我们展示的要复杂得多。“你必须把它进一步固定下来,使之符合我们可以复制的情况。”JensGustedt,谢谢。发现了问题。我是用析构函数以外的方法销毁互斥体和condvar的:(我不这么认为。From:“如果需要可预测的调度行为,那么调用pthread_cond_broadcast()或pthread_cond_signal()的线程将锁定互斥体。”在发送信号之前锁定或不锁定互斥体也在SO中讨论过很多次。简言之:“应该锁定”我不明白为什么这会让你感到惊讶。在被破坏的结构上调用任何函数(但是
init
)都是未定义的行为,不是吗?我会说,任何事情都可能发生。
#0  __lll_lock_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:136
#1  0x00007ffff73e291c in pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:259
#0  __lll_lock_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:136
#1  0x00007ffff73e30b1 in pthread_cond_signal@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S:142
3967    In Task, sleeping...
3967    My Turn to do the task...
3967    In Task, sleeping...
3973    wait...
3973    waiting...
3976    <output from some other thread>
3967    Before trying to acquire lock
3967    After acquiring lock
3967    Before broadcast