代码之家  ›  专栏  ›  技术社区  ›  Matthew Iselin

POSIX线程:条件变量-重点是什么?

  •  4
  • Matthew Iselin  · 技术社区  · 16 年前

    我最近一直在使用pthreads,但有一点我仍然不太明白。我知道条件变量被设计为等待特定条件实现(或被“信号化”)。我的问题是,这与普通互斥有什么区别?

    据我所知,条件变量不只是一个带有额外逻辑的互斥锁吗 另一个

    伪代码示例:

    mutex mymutex;
    condvar mycond;
    int somevalue = 0;
    
    onethread()
    {
        lock(mymutex);
    
        while(somevalue == 0)
            cond_wait(mycond, mymutex);
    
        if(somevalue == 0xdeadbeef)
            some_func()
    
        unlock(mymutex);
    }
    
    otherthread()
    {
        lock(mymutex);
    
        somevalue = 0xdeadbeef;
    
        cond_signal(mycond);
    
        unlock(mymutex);
    }
    

    因此,本例中的cond_wait将解锁 mymutex mycond 发出信号。

    3 回复  |  直到 15 年前
        1
  •  14
  •   ninjalj    15 年前

    这两种结构完全不同。互斥体旨在提供对某种资源的序列化访问。条件变量意味着允许一个线程通知另一个线程某个事件已经发生。

        2
  •  13
  •   Logan Capaldo    16 年前

    while(1) {
      lock(mymutex)
      if( somevalue != 0)
         break;
      unlock(mymutex);
    }
    
    if( somevalue == 0xdeadbeef )
      myfunc();
    

    在这个线程中,您将处于一个紧密的循环中,消耗大量cpu,并导致大量锁争用。如果锁定/解锁互斥锁足够便宜,那么您可能会遇到其他线程甚至没有机会获得锁的情况(尽管现实世界中的互斥锁通常区分拥有线程和拥有锁,并且具有公平性的概念,因此这在现实中不太可能发生)。

    你可以通过睡懒觉来减少忙碌的等待,

    while(1) {
      lock(mymutex)
      if( somevalue != 0)
         break;
      unlock(mymutex);
      sleep(1); // let some other thread do work
    }
    

    但是睡多久才是好觉呢?你基本上只是在猜测。运行时也不能告诉你为什么要睡觉,或者你在等什么。条件变量使运行时至少在一定程度上了解当前同一事件中哪些线程感兴趣。

        3
  •  3
  •   leiz    16 年前

    简单的答案是,您可能希望从条件变量中唤醒多个线程,但互斥体只允许一个线程执行受保护的块。