2014-11-07 1 views
0

다음 코드는 생산자 - 소비자 예제를 보여줍니다. 제품이 생산되면 소비자가이 제품을 받게됩니다.sem_wait가 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 

내 코드에 문제가 있습니까?

+0

@Mat, 그것은 여전히 ​​작동하지 않습니다. – ahui

답변

1

귀하의 문제는 당신이 당신의 세마포어를 삭제되지 않습니다 것입니다. 그래서 열 때 오래된/나쁜 상태를 회복합니다. O_EXCL으로 열려고하면이 문제를 관찰 할 수 있습니다.

sem_unlink()으로 삭제할 간단한 명령을 쓰거나 semctl과 함께 사용하기 전에 초기화하십시오.

는 또한

ALOS는 POSIX가 /로 시작하는 이름을 가지고 있어야 세마포어라는 점에 유의 ... sem_open하지 022에 적절한 값을 설정해야합니다.

변경 주에 시작 :

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; 
} 
+0

'O_CREAT'를'O_EXCL'로 바꿨습니다. 문제. – ahui

+0

아니요 O_CREAT | O_EXCL (둘 다) 세마포어가 이미 있음을 나타냅니다. –

+0

문제가 해결되지는 않습니다. 이를 해결하려면 열기/만들기 전에 세마포어를 삭제해야합니다. 'sem_unlink ("blank_number")를 추가하십시오; sem_unlink ("prodcut_number");'before sem_opens. –

0

아마 sem_open 대신에 이름없는 세마포어 sem_init를 사용하려고 :

sem_t semaphore; 
int ret = sem_init(&semaphore, 0, 0); 
+0

'sem_init'은 Mac OSX에서 더 이상 사용되지 않습니다. (-1을 반환합니다) – ahui

+0

젠장, 리눅스 사용자로 발견되었습니다 ... – Coconop