2014-03-04 34 views
1

可以说我有一个缓冲区,它有3个生产者线程和5个消费者线程插入缓冲区并从缓冲区消耗。使用线程信号量和多线程的C中的生产者/消费者

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

只有在没有生产者访问它的情况下,最多3位消费者才能查看缓冲区中的顶层元素。如果多于1个消费者线程访问缓冲区,则最后一个要离开的线程必须删除顶部元素。

现在这是部分的类分配,并且该分配明确规定使用信号量。然而,我想不出一种只用信号量来真正实现这种措辞的方法。

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

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个消费者加入另一个?看起来我需要使用信号量之外的东西。

此外,如果需要,请更正任何逻辑,这只是一个普遍的想法。

+0

SO不是代码审查或意见的网站。你有一个具体的技术问题吗? –

+1

你想让所有的消费者获得一份数据? – const

+0

@Jens Gustedt:所以基本上你希望我删除这篇文章,然后发布我的真实代码并说:“我如何让三名消费者只用信号灯?”当这是我问的问题的简化版本时,似乎很愚蠢。 const:所有消费者?只有在任何时候进来的3个,但是他们都应该得到一个副本。 – user2079828

回答

2

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

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); 
} 
+0

我想到了这个,然后立即因为某种原因解雇了它。我认为制片人可能会陷入等待。三个单独的生产者线程是否可以触发第一个sem_wait()?然后他们都会陷入无法脱身的境地。 – user2079828

+1

是的,你是对的。出于某种原因,我认为只会有一个制片人。我会在一分钟内修好它。 – nosid

+0

是的,这是我刚刚实施的。你以前的帖子让我在这里。恰恰是答案,我很早就驳回了。我认为这对生产者可能是“不公平的”,因为他们必须等待3个锁,其中消费者只需要1个。谢谢。 – user2079828