【发布时间】:2016-06-21 09:08:11
【问题描述】:
这是我对信号量的理解:
如果您在这里有一个信号量,称为 sem1,并且在它之后有一个临界区。然后,一旦输入信号量后的代码,它将完全执行。所以如果你有以下伪代码:
sem_wait(sem1)
//#CRITICAL SECTION
//code 1
//code 2
sem_post(sem1)
那么两行代码 1、代码 2 将在没有任何暂停的情况下执行,对吗?即使临界区有 500 行代码也是如此,对吗?
现在,我之所以问这个问题是因为我在以下代码中遇到了一个非常奇怪的错误:
while (1) {
int binary;
sem_wait(&shared_mem->bufferUnderflow);
printf("we passed the underflow\n");
sem_wait(&shared_mem->binary);
sem_getvalue(&shared_mem->binary, &binary);
printf("currentIndex is %d",shared_mem->frontBuffer);
printf("we passed the binary:%d\n",binary);
//*****HERE******
printf("currentIndex is %d",shared_mem->frontBuffer);
//if we pass here then we can safely take the Job
Job currentJob = shared_mem->jobs[shared_mem->frontBuffer];
printf("we took a job");
int currentIndex = shared_mem->frontBuffer;
printf("we took currentIndex");
//change the indeces now that we have popped the latest one
shared_mem->frontBuffer = (shared_mem->frontBuffer + 1) % sizeBuffer;
printf("we changed the index");
//shared_mem->freeIndex = (shared_mem->freeIndex + 1) % sizeBuffer;
sem_post(&shared_mem->binary);
sem_post(&shared_mem->bufferOverflow);
//consume the Job
printf("Printer starts printing %d pages from Buffer[%d]", (currentJob).pages,currentIndex);
sleep(currentJob.duration);
}
return 0;
}
在这里,我假设当“我们通过二进制文件:0”这一行被打印时,之后的所有代码都应该被执行。 但事实并非如此。之后的任何代码 //*****这里****** 不会立即执行。只有当我通过生产者向缓冲区中插入其他内容时,关键部分的其余部分才会被执行。
抱歉,帖子太长了。如果有人对可能导致这种情况的原因有任何暗示,请告诉我。 任何帮助都非常感谢!
【问题讨论】:
-
您是在使用现有的信号量库,还是自己编写?
-
默认的信号量计数值是多少?为什么不只是互斥锁(即:带有
count=1的信号量)? -
@callyalater 好点。如果 OP 包装了他/她自己的信号量调用,它们可能不是原子的。
-
通常,通常情况下,您需要三个信号量来管理一个有界队列,或者两个信号量和一个互斥体,因此使用 'bufferUnderflow'、'bufferOverflow' 和 'binary'管理队列。
-
注意 - 你应该清除 printf() 的,否则你可能会得出一个错误的结论。发生在之前/之后。
标签: c semaphore producer-consumer critical-section