【问题标题】:pthread condition signal does not lock mutexpthread 条件信号不锁定互斥体
【发布时间】:2012-10-05 09:02:59
【问题描述】:

我的互斥锁似乎已解锁。 我的代码看起来像这样(不是实际代码)(使用 pthread):

  thread
    {
    int id=...;
    //locked aditional mutex _m2
    mutex_lock(&_m);
    varx=valuex;//irelevant
    print("th%d signaling listener",id);
    cond_signal(&_c);
    print("th%d signaled listener",id);
    mutex_unlock(&_m);
    //unlocked additional mutex _m2
    }

 listener
    {
    tc=0
    mutex_lock(&_m);
    while(tc<threadcount)
        {
        cond_wait(&_c,&_m);
        print("working");
        tc++
        work;
        }
    mutex_unlock(&_m);
    }

正常(预测)输出:

    th0 signaling listener;
    working;
    th0 signaled listener;

    th1 signaling listener;
    working;
    th1 signaled listener;

我的输出:

    0 signaling listener;
    working;
    0 signaled listener;

    1 signaling listener;
    1 signaled listener;

..所以线程跳过(侦听器不执行也不锁定_m)打印输出

我已经用 helgrind (full) 对其进行了分析,我没有错误,但我的应用程序在侦听器处停止,因为据他说,他正在等待一切完成。

注意事项: 听众是可加入的。 额外的互斥锁 _m2 没有帮助。 线程分离。我有大约 800 个分离的线程来避免堆栈问题,最多 50 个同时使用信号量来限制线程数。 代码为 3-4 个线程工作

【问题讨论】:

    标签: pthreads signals mutex race-condition


    【解决方案1】:

    pthread_cond_signal() 不会解锁任何互斥锁。它不应该(没有互斥体传递给它)。如果至少有一个线程正在等待发出信号的条件变量,则该线程将在它可以重新获取它传递给pthread_cond_wait() 的互斥锁时被调度。

    在您的情况下,您的侦听器似乎在等待与其他线程信号 (_c) 不同的条件 (_s)。

    如果你解决了这个问题,你还会遇到这样的问题,即在等待条件变量的线程和发出信号的线程之间似乎没有任何共享状态。看起来您的tc 计数器实际上应该是一个共享变量,受_m 互斥锁保护。然后你的线程会这样做:

    pthread_mutex_lock(&_m);
    tc++;
    if (tc >= threadcount)
        pthread_cond_signal(&_c);
    pthread_mutex_unlock(&_m);
    

    听者会这样做:

    pthread_mutex_lock(&_m);
    while (tc < threadcount)
        pthread_mutex_wait(&_c, &_m);
    pthread_mutex_unlock(&_m);
    

    只有在所有线程都命中信号代码后,侦听器才会继续,这似乎是您所追求的。

    您也可以使用pthread_barrier_wait(),这似乎是您正在实施的。

    【讨论】:

    • 我的错误 _s 和 _c 是同一个变量,我只是错过了键入它。我以使用队列存储数据并将其锁定在 th 中(用于推送)和侦听器中(用于弹出)的方式修复了我的代码。我将研究障碍等待,因为我的代码确实有效,但我似乎有一些由 helgrind 报告的锁定失败(最后是 1 - 可能是一个阻止互斥锁解锁的错误)。看着障碍对我没有帮助。
    • 我确实有一个共享变量 (x) 但由于所有线程都只从它读取,所以我不锁定它。侦听器仅检查是否所有数据都已处理,如果未处理(q-mutexed)中的数据。 th 将进一步的数据从已知大小的共享变量 (x) 添加到 (q-mutexed)。代码有效。
    • @LucianMLI:为了正确、不随意地使用 pthread 条件变量,必须涉及某种可写的共享状态。
    • 是的。 q 是可写的,共享的(互斥的)我在评论中忘记了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-05
    • 2013-06-06
    • 1970-01-01
    • 2015-06-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多