1
bool flag=false;
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond=PTHREAD_COND_INITIALIZER;

void function1()
{
    pthread_mutex_lock(&mutex);
    while(!flag)
    {
    //#2
        pthread_cond_wait(&cond,&mutex);
    }
    pthread_mutex_unlock(&mutex);
}

void function2()
{
    flag=true;
    pthread_cond_signal(&cond);
}

这是情况。两个线程:thread1 和 thread2 分别运行在 function1 和 function2 上。

由于 CPU 调度,thread1 在 #2 处停止。

thread2 开始执行并将标志更改为 true。

thread1 开始等待,但它会永远等待。

当我想在不锁定互斥锁的情况下通知其他线程时如何避免这种情况。

4

2 回答 2

4

flag这就是为什么在更新谓词 ( )时必须锁定互斥锁的原因。没有替代。

pthread_mutex_lock(&mutex);
flag = true;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);

(如果你愿意,你可以在pthread_cond_signal()后面移动pthread_mutex_unlock())。

于 2013-08-01T04:59:15.223 回答
1

caf 的回答已经说明了一切,但让我补充一下为什么这里需要锁定的理由,因为一开始这可能有点令人困惑。

从概念上讲,条件变量表示已达到所需状态。它本身并不代表该状态(在您的情况下,状态由flag变量表示)。这就是为什么您仍然需要一个额外的互斥锁的原因:对条件变量本身的并发更改受到保护(例如,您可以同时从多个线程通知),而对保持该状态的数据的更改不受保护。这就是条件变量通常与互斥体配对的原因:条件变量发出状态变化的信号,而互斥体保护状态免受竞争。

在某些情况下,您不需要状态的互斥锁(例如,如果您的标志是原子变量)。当您将无锁数据结构与条件变量混合使用时,通常会发生这种情况。这是一种气味。条件变量用于等待特定条件,它们本质上总是阻塞的。使用无锁数据结构,您可以表达您永远不想阻塞的意图。将两者混合通常首先表明设计存在缺陷。

于 2013-08-01T06:14:30.200 回答