Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.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_wait无互斥锁的潜在缺陷_C_Multithreading_Pthreads - Fatal编程技术网

pthread_cond_wait无互斥锁的潜在缺陷

pthread_cond_wait无互斥锁的潜在缺陷,c,multithreading,pthreads,C,Multithreading,Pthreads,在以下链接中: @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_unl

在以下链接中:

@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和线程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\u mutex\u unlock(&mutex)
    ,并被抢占
  • 线程2获取锁,
    pthread\u mutex\u lock(&mutex)
    ,更改状态、解锁、发出信号并被抢占
  • 线程#1再次被调度并在条件下等待,
    pthread_cond\u wait(&cond)
您有一个问题可能会升级:

  • 信号已丢失:根据您的应用程序,信号本身可能更严重或更不严重
  • 但是,即使信号本身并不重要,线程#1现在仍被卡住,等待已经发生的信号
  • 即使线程#1没有做一些重要的事情,如果稍后的线程#2等待线程#1,您也会有一个死锁
因此,为了避免这个问题,线程#1必须在释放锁时立即等待,然后其他线程才有机会发出状态信号

我认为与其说是唤醒/锁定转换,不如说是解锁/等待转换

我对唤醒/锁定转换绝对需要原子化的场景很好奇

希望这有帮助