[英]why sem_wait doesn't wait semaphore on mac OSX?
The following code shows a producer-consumer example: Once a product is produced, the consumer will get this product.下面的代码展示了一个生产者-消费者的例子:一旦产品被生产出来,消费者就会得到这个产品。
But I'm surprised that the consumer will sill get a product when there is no product.但令我惊讶的是,当没有产品时,消费者仍然会得到产品。
#include <stdlib.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <semaphore.h>
#define NUM 5
int queue[NUM];
int i;
sem_t *blank_number, *product_number;
void *producer(void *arg) {
int p = 0;
while (1) {
sem_wait(blank_number);
queue[p] = rand() % 1000 + 1;
printf("Produce queue[%d]:%d\n", p, queue[p]);
i = sem_post(product_number);
//printf("i_p=%d\n", i);
p = (p+1)%NUM;
sleep(rand()%5);
}
}
void *consumer(void *arg) {
int c = 0;
while (1) {
sem_wait(product_number);
printf("Consume queue[%d]:%d\n", c, queue[c]);
queue[c] = 0;
i = sem_post(blank_number);
//printf("i_c=%d\n", i);
c = (c+1)%NUM;
sleep(rand()%5);
}
}
int main(int argc, char *argv[]) {
pthread_t pid, cid;
//set blank_number to NUM
blank_number = sem_open("blank_number", O_CREAT, S_IRWXU, NUM);
if(blank_number == SEM_FAILED){
perror("open blank_number");
return 1;
}
//set product_number to 0
product_number = sem_open("product_number", O_CREAT, S_IRWXU, 0);
if(product_number == SEM_FAILED){
perror("open product_number");
return 1;
}
pthread_create(&pid, NULL, producer, NULL);
pthread_create(&cid, NULL, consumer, NULL);
pthread_join(pid, NULL);
pthread_join(cid, NULL);
sem_close(blank_number);
sem_close(product_number);
return 0;
}
In my test result, there is only one product : 808, but the consumer gets two products : 808 and 0;在我的测试结果中,只有一种产品:808,但是消费者得到了两种产品:808和0;
$ sudo ./a.out
Produce queue[0]:808
Consume queue[0]:808
Consume queue[1]:0
Is there any wrong in my code?我的代码有什么问题吗?
Your problem is that you never deleted your semaphores.你的问题是你从来没有删除过你的信号量。 So when you open them you recover some old/bad state.
所以当你打开它们时,你会恢复一些旧的/坏的状态。 Try to open with
O_EXCL
you will be able to observe the problem.尝试用
O_EXCL
打开你就能观察到问题。
Write a simple command to delete them with sem_unlink()
or initialize them before using them with semctl
.编写一个简单的命令来使用
sem_unlink()
删除它们或在使用semctl
之前初始化它们。
You also need to set the appropriate values in sem_open
not 022...您还需要在
sem_open
设置适当的值而不是 022...
Alos note that POSIX named semaphores should have a name starting with /
.请注意,POSIX 命名信号量的名称应该以
/
开头。
Change the beginning of your main to :将 main 的开头更改为:
sem_unlink("blank_number");
sem_unlink("product_number");
//set blank_number to 1
blank_number = sem_open("blank_number", O_CREAT|O_EXCL, S_IRWXU, 1);
if(blank_number == SEM_FAILED){
perror("open blank_number");
return 1;
}
//set product_number to 0
product_number = sem_open("product_number", O_CREAT|O_EXCL, S_IRWXU, 0);
if(product_number == SEM_FAILED){
perror("open product_number");
return 1;
}
Maybe try to use sem_init
with an unnamed semaphore instead of sem_open
:也许尝试将
sem_init
与未命名的信号量一起使用,而不是sem_open
:
sem_t semaphore;
int ret = sem_init(&semaphore, 0, 0);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.