【问题标题】:Single provider, single consumer. Which is suitable for conditional variable: pthread_cond_t, sem_t or pthread_mutex_t?单一提供者,单一消费者。哪个适合条件变量:pthread_cond_t、sem_t 或 pthread_mutex_t?
【发布时间】:2012-04-26 03:39:35
【问题描述】:

有:

一个条件变量“var”:var的值只能是0或1;

一个提供者线程“thP”:从网络接收到数据时,设置var 1(可用);

一个消费者线程“thC”:等待() for var。得到 var 后,将其设置为 0(不可用),然后处理。

.

我找到了两种方法来实现这个简单的模型:

(1) 使用 pthread_cond_t 作为 var。 这个方法需要一个额外的互斥锁和一个回调函数来解锁互斥锁,同时线程将被清理。

(2) 使用 sem_t 作为 var。 这种方法可能会导致“var>1”的情况。 thC 可能会执行多个 wait() 操作来将 var 的值减小到 1。

.

问题是:

要实现这个简单的模型“单一提供者,单一消费者,一个条件变量”,我应该为 var、pthread_cond_t、sem_t 使用哪种类型,还是简单地将 pthread_mutex_t 用作二进制信号量?

.

非常感谢!

【问题讨论】:

    标签: linux pthreads conditional semaphore producer-consumer


    【解决方案1】:

    对于单个消费者、单个提供者、有界队列示例,典型的做法是使用一个锁保护两个条件变量(一个在“队列未满”时发出信号,一个在“队列不为空”时发出信号) .

    算法如下:

    post(item):
      lock;
      while (queue is full):
        wait(cvar_queue_not_full);
      queue.push(item)
      signal(cvar_queue_not_empty);
      unlock;
    
    consume():
      lock;
      while (queue is empty):
        wait(cvar_queue_not_empty);
      item = queue.shift(item);
      signal(cvar_queue_not_full);
      unlock;
      return item;
    

    这本质上是一个有界信号量,但允许您以原子方式调整信号量并同时推送/弹出队列。不幸的是,POSIX 信号量是无限的,并且不提供原子性。

    【讨论】:

    • 一个不提供原子性的信号量?那不是信号量!
    • @MartinJames,信号量本身是原子的。但是,您不能同时添加到队列和发布到 posix 信号量原子 together 而不在其之上添加一些额外的锁定形式。
    • 是的 - 队列必须是线程安全的,因此您确实需要一个锁(或线程安全的无锁队列)以及信号量。
    • 感谢您的回答。我从stackoverflow.com/questions/7478684/… 找到了上述算法的 Linux 实现。程序有效。谢谢!
    猜你喜欢
    • 2011-12-16
    • 1970-01-01
    • 1970-01-01
    • 2010-11-17
    • 1970-01-01
    • 1970-01-01
    • 2018-03-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多