【问题标题】:Producer/Consumer in C with pthread semaphores and multiple threads带有 pthread 信号量和多线程的 C 中的生产者/消费者
【发布时间】:2014-03-04 06:28:25
【问题描述】:

假设我有一个缓冲区,其中包含 3 个生产者线程和 5 个消费者线程,它们向/从缓冲区插入和消费。

我只想允许 1 个生产者或最多 3 个消费者线程在任何给定时间访问缓冲区。

只有在没有生产者访问它的情况下,最多 3 个消费者可以查看缓冲区中的顶部元素。如果超过 1 个消费者线程确实访问了缓冲区,则最后离开的线程必须删除顶部元素。

现在这是类分配的部分,并且分配明确声明使用信号量。但是,我想不出一种仅使用信号量来真正实现这种措辞的方法。

伪代码 - 我认为 - 应该是这样的:(我不担心缓冲区是空的还是满的,只是这个问题的子部分)

sem_init(&binary, 0, 1);  //Init binary semaphore to 1
sem_init(&consumerCount, 0 , 3);  //Allows 3 consumers to access

producer()
{
    createItem()
    sem_wait(&binary)
    appendItem()
    sem_post(&binary)
}

//The above assures nothing else can access buffer while appending an item

consumer()
{

    while( binary unlocked)
    {
        sem_wait(&binary) and sem_wait(&consumerCount)  //Locks the producers out
                                                        //Allows 3 consumers in 
        peek()  //Gets copy of top item
        if( last consumer out )
        {
            delete()  //Deletes top item
            sem_post(&binary)  //Allow producer access back since last one out
        }
        sem_post(&consumerCount)         

    }
}

我认为这是逻辑的要点,问题是如何仅使用信号量来实现这一点。如何只允许 1 个带有信号量的生产者进入,但在另一侧允许 3 个消费者进入?看来我需要使用信号量以外的东西。

另外,如果需要,请更正任何逻辑,这只是一个大概的想法。

【问题讨论】:

  • SO 不是代码审查或意见的网站。您有具体的技术问题吗?
  • 您希望所有消费者都获得数据的副本吗??
  • @Jens Gustedt:所以基本上你希望我删除这篇文章,然后发布我的真实代码并说,“我如何让三个消费者只使用信号量?”当这是我要问的问题的简化版本时,这似乎很愚蠢。 const:所有消费者?只有在任何给定时间进来的 3 个,但是是的,他们都应该得到一份副本。
  • 通过一些信号量的实现,可以在一次操作中获取多个permit。例如,参见 Java 中的 Semaphore。您的 信号量 也可以做到这一点吗?
  • @nosid:我正在使用 pthreads...我应该这样规定。据我所知,没有。但是,我只是在很短的时间内阅读了它们。这里似乎需要某种类型的信号。基本上我认为问题源于:有没有办法只在 pthreads 中发出信号量未锁定的信号?

标签: c multithreading pthreads producer-consumer


【解决方案1】:

你可以用两个信号量来解决这个问题。第一个信号量用于生产者的独占访问。第二个信号量用于 shared 访问。生产者试图获得所有三个许可以锁定消费者。

sem_init(&exclusive, 0, 1);
sem_init(&shared, 0, 3);

void producer()
{
    sem_wait(&exclusive);
    sem_wait(&shared);
    sem_wait(&shared);
    sem_wait(&shared);
    // critical section
    sem_post(&shared);
    sem_post(&shared);
    sem_post(&shared);
    sem_post(&exclusive);
}

void consumer()
{
    sem_wait(&shared);
    // critical section
    sem_post(&shared);
}

【讨论】:

  • 我想到了这个,然后出于某种原因立即将其驳回。我认为制片人可能会陷入等待中。三个独立的生产者线程可以触发第一个 sem_wait() 吗?然后他们都会被困在无法脱身的地方。
  • 是的,你是对的。出于某种原因,我认为只有一个制片人。我会在一分钟内修复它。
  • 是的,这就是我刚刚实现的。你以前的帖子把我带到了这里。正是答案,我很早就驳回了它。我认为这对生产者来说可能是“不公平的”,因为他们必须等待 3 把锁,而消费者只需要 1 把。谢谢。
猜你喜欢
  • 1970-01-01
  • 2013-11-19
  • 1970-01-01
  • 1970-01-01
  • 2020-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多