代码之家  ›  专栏  ›  技术社区  ›  Emiliano

为什么需要围绕pthread等待条件进行while循环?

  •  50
  • Emiliano  · 技术社区  · 16 年前

    pthread_mutex_lock(&m);
    while(!condition)
         pthread_cond_wait(&cond, &m);
    // Thread stuff here
    pthread_mutex_unlock(&m);
    

    while(!condition) 即使我使用 pthread_cond_signal()

    pthread_cond_broadcast() 全部 等待线程,其中一个线程可以在解锁互斥体之前再次使条件为假(从而将执行转移到另一个被唤醒的线程,该线程此时不应执行)。 但如果我使用

    pthread_mutex_lock(&m);
    pthread_cond_wait(&cond, &m);
    // Thread stuff here
    pthread_mutex_unlock(&m);
    

    pthread_mutex_lock(&m);
    condition = true;
    pthread_cond_signal(&cond); // Should wake up *one* thread
    pthread_mutex_unlock(&m);
    
    2 回复  |  直到 7 年前
        1
  •  47
  •   Chris Lu    15 年前

    您应该将pthread_cond_wait放入while循环的真正原因不是因为虚假唤醒。即使您的条件变量没有虚假唤醒,您仍然需要循环来捕获常见类型的错误。为什么?考虑一下如果多个线程在相同条件下等待会发生什么:

    Thread 1                         Thread 2           Thread 3
    check condition (fails)
    (in cond_wait) unlock mutex
    (in cond_wait) wait
                                     lock mutex
                                     set condition
                                     signal condvar
                                     unlock mutex
                                                        lock mutex
                                                        check condition (succeeds)
                                                        do stuff
                                                        unset condition
                                                        unlock mutex
    (in cond_wait) wake up
    (in cond_wait) lock mutex
    <thread is awake, but condition
    is unset>
    

        2
  •  17
  •   Steve Jessop    13 年前

    假设你不检查情况。那么通常你无法避免以下坏事的发生(至少,你无法在一行代码中避免它):

     Sender                             Receiver
    locks mutex
    sets condition
    signals condvar, but nothing 
      is waiting so has no effect
    releases mutex
                                        locks mutex
                                        waits. Forever.
    

    当然,您的第二个代码示例可以通过执行以下操作来避免这种情况:

    pthread_mutex_lock(&m);
    if (!condition) pthread_cond_wait(&cond, &m);
    // Thread stuff here
    pthread_mutex_unlock(&m);
    

    那么,如果最多只有一个接收器,并且 cond_signal

    推荐文章