[英]why sem_wait doesn't wait semaphore on mac OSX?
下面的代碼展示了一個生產者-消費者的例子:一旦產品被生產出來,消費者就會得到這個產品。
但令我驚訝的是,當沒有產品時,消費者仍然會得到產品。
#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;
}
在我的測試結果中,只有一種產品:808,但是消費者得到了兩種產品:808和0;
$ sudo ./a.out
Produce queue[0]:808
Consume queue[0]:808
Consume queue[1]:0
我的代碼有什么問題嗎?
你的問題是你從來沒有刪除過你的信號量。 所以當你打開它們時,你會恢復一些舊的/壞的狀態。 嘗試用O_EXCL
打開你就能觀察到問題。
編寫一個簡單的命令來使用sem_unlink()
刪除它們或在使用semctl
之前初始化它們。
您還需要在sem_open
設置適當的值而不是 022...
請注意,POSIX 命名信號量的名稱應該以/
開頭。
將 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;
}
也許嘗試將sem_init
與未命名的信號量一起使用,而不是sem_open
:
sem_t semaphore;
int ret = sem_init(&semaphore, 0, 0);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.