没有互斥的pthread_cond_wait的潜在缺陷

时间:2013-11-10 23:30:47

标签: c multithreading pthreads

在以下链接中: Why do pthreads’ condition variable functions require a mutex?

@nos描述了在没有互斥锁的情况下实现pthread_cond_wait()的潜在漏洞:

while(1) {
    pthread_cond_wait(&cond); //imagine cond_wait did not have a mutex
    pthread_mutex_lock(&mutex);
    char *data = some_data;
    some_data = NULL;
    pthread_mutex_unlock(&mutex);
    handle(data);
}

“不起作用,在唤醒和抓住互斥锁之间仍有可能出现竞争条件。”

我不明白如何在唤醒和获取互斥锁之间出现竞争条件?

1 个答案:

答案 0 :(得分:0)

事实上,这个例子并未显示问题,但作为一般原则,当有两条指令时,竞争条件就会存在。

这是一个有希望说明问题的例子。

假设您自己管理互斥锁,并且您有两个线程,线程#1 线程#2

  • 线程#1 需要修改某些共享状态
  • 它获取互斥锁并更改状态
  • 它会释放互斥锁并在继续之前等待某些事情发生

以下是一些代码:

    pthread_mutex_lock(&mutex);
    // change state
    pthread_mutex_unlock(&mutex);
    pthread_cond_wait(&cond);

还有更多:

  • 线程#2 等待互斥锁,更改共享状态并使用条件变量发送线程#1 以提供线程#1
  • 之前有机会做某事

以下是代码:

    pthread_mutex_lock(&mutex);
    // change state
    pthread_mutex_unlock(&mutex);
    pthread_cond_signal(&cond);

这是一个讨厌的场景:

  • 线程#1 获取锁定并更改共享状态
  • 主题#1 释放锁定pthread_mutex_unlock(&mutex)被抢先
  • 线程#2 获取锁定,pthread_mutex_lock(&mutex),更改状态,解锁,信号并抢占
  • 线程#1 再次安排并等待条件pthread_cond_wait(&cond)

您有一个问题可以升级:

  • 信号已丢失:根据您的应用,它本身可能或多或少具有关键性
  • 但即使信号本身并不重要,线程#1 现在卡住等待已经发生的信号
  • 即使线程#1 没有做一些重要事情,如果以后线程#2 等待<死锁 EM>线#1

为了避免这个问题,线程#1 必须在任何其他线程有机会发出信号之前释放锁定时立即等待。

恕我直言,解锁/等待转换唤醒/锁定转换更需要原子。

我很想知道唤醒/锁定转换绝对需要是原子的场景......

希望这有帮助。