如何在另一个线程准备好之前阻止线程递减信号量?

时间:2016-06-15 17:24:46

标签: c pthreads semaphore

我在循环中执行sem_post()但它似乎没有增加目标信号量的值。这是代码:

void* producerFunc(void* arg)
{
    int x, d, i, semValue, semTaken;

    sem_getvalue(&sem_posTaken, &semTaken);
    sem_getvalue(&sem_posAvaliable, &semValue);
    while(n_insertions < N_PRODUCTS)
    {
        sem_wait(&sem_posAvaliable);    //Verifica se tem espaço vazio no buffer
        sem_getvalue(&sem_posAvaliable, &semValue);
        x = produce_item();
        sem_wait(&db);
        insert_buffer(x);
        sem_post(&db);

        printf("n_insertions: %d\n", n_insertions);
        if(n_insertions % 5 == 0){
            sem_getvalue(&sem_posTaken, &semValue);
            for(i=0; i< Buffer_Size; i++)
            {
                sem_getvalue(&sem_posTaken, &semTaken);
                printf("VOU DAR POST %d\n", semTaken);
                sem_post(&sem_posTaken);   //Sinaliza para o consumidor que já tem item no buffer
                sem_getvalue(&sem_posTaken, &semTaken);
                printf("DEI POST %d\n", semTaken);
            }
        }
    }
    pthread_exit(NULL);
}

在最初发布问题之后,我将问题追溯到运行此代码的另一个线程的行为:

void* consumerFunc(void* arg)
{
    int d;
    struct sConsumer* cons = (struct sConsumer*) arg;
    while(n_consumed < N_PRODUCTS)
    {
        n_consumed++;
        sem_wait(&sem_posTaken); //Verifica se já tem item dentro do Buffer_Size
        sem_wait(&mutex);       //Garante acesso exclusivo
        consumers++;
        if(consumers == 1)
            sem_wait(&db);
        remove_buffer(cons->id);
        sem_getvalue(&sem_posTaken, &d);
        printf("Taken: %d\n", d);
        sem_post(&mutex);
        sem_post(&sem_posAvaliable);
        sem_wait(&mutex);
        consumers--;
        if(consumers == 0)
            sem_post(&db);
        sem_post(&mutex);

    }
    pthread_exit(NULL);

我打算运行ProducerFunc的线程填充整个缓冲区,然后将sem_postaken信号量增加到与占用的槽数相对应的值。然而,在生产者sem_post()上,被阻塞等待该信号量的消费者继续,递减信号量并循环再次等待。这解释了为什么生产者在执行sem_getvalue()时从未看到大于零的值。

如果生产者执行了它想要执行的所有增量,我怎样才能阻止消费者减少信号量?

1 个答案:

答案 0 :(得分:2)

等待信号量的重点是,一旦信号量的值大于零,这样做的线程就可以立即进行。因此,如果您不希望消费者在生产者发布到您的信号量时立即继续,那么您必须确保消费者当时没有等待该信号量。

我怀疑你试图以一种他们不支持的方式使用信号量。信号量值应该被解释为传达的信息是信号量可以在下一个增量之前递减而没有阻塞的次数。尝试对该数据进行进一步解释通常是一个坏主意。而且,一旦返回,该数据必须被视为陈旧。使用共享变量(通过适当的同步访问)来传达任何其他所需的数据。

话虽如此,你确实有第二个信号量,你命名为&#34; mutex&#34;。你用它做什么的细节看起来很可疑,但是如果你真的想阻止消费者继续进行直到生产者准备好,并且生产者的准备就绪没有得到{{1的充分传达信号量,然后立即明显的解决方案是使用单独的信号量来做到这一点 - 也许是sem_posTaken