簡體   English   中英

為什么 sem_wait 在 mac OSX 上不等待信號量?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM