gpt4 book ai didi

c - 如何防止一个线程递减信号量,直到另一个线程准备好为止?

转载 作者:行者123 更新时间:2023-11-30 18:51:09 25 4
gpt4 key购买 nike

我正在循环内执行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() 时永远不会看到大于零的值。

如何防止消费者减少信号量,直到生产者执行完其打算执行的所有增量?

最佳答案

等待信号量的全部意义在于,一旦信号量的值大于零,执行此操作的线程就可以立即继续。因此,如果您不希望消费者在生产者发布到您的信号量时立即继续,那么您必须确保消费者当时没有等待该信号量。

我怀疑您正在尝试以信号量不支持的方式使用信号量。信号量的值应解释为传达的唯一信息是信号量在下一次增量之前可以无阻塞地递减的次数。尝试对这些数据进行任何进一步的解释通常是一个坏主意。此外,该数据一返回就必须被视为过时。使用共享变量(通过适当的同步访问)来传达任何其他所需的数据。

话虽如此,您确实有第二个信号量,您将其命名为“互斥体”。您正在使用它做什么的细节看起来很可疑,但如果您确实想阻止消费者在生产者准备好之前继续进行,并且 sem_posTaken 信号量无法充分传达生产者的准备情况,那么显而易见的解决方案是使用单独的信号量来执行此操作 - 也许是互斥体。

关于c - 如何防止一个线程递减信号量,直到另一个线程准备好为止?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37841932/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com