2016-04-20 58 views
0

在我的生產者和消費者問題中,我使用sem_open來創建信號量。我如何測試sem_open是否以正確的方式工作?使用sem_open初始化信號量

該程序可以編譯,但是當我運行該程序時,它什麼都不打印。我測試程序,發現問題可能是關於sem_open()。我發現如果我在程序中註釋sem_open(),程序將正常運行。

#include <stdio.h> 
#include <pthread.h> 
#include <semaphore.h> 
#include <stdlib.h> 
#include <unistd.h> 

#define BUFFER_SIZE 10 

int buffer[BUFFER_SIZE]; 
pthread_t pro_thread, con_thread; 
pthread_mutex_t mutex; 
int counter = 0; 
sem_t *empty, *full; 

void print_buffer(int counter) { 
    for (int i = 0; i < counter; i ++) 
    { 
     printf("*"); 
    } 
    printf("\n"); 
} 

void* producer(void* var) { 
    int item; 
    while(1) { 
     item = rand() % 100 + 1; 
     sem_wait(empty); 
     pthread_mutex_lock(&mutex); 

     while (counter == BUFFER_SIZE) 
      ; // waiting 

     if(counter < BUFFER_SIZE) { 
      buffer[counter] = item; 
      counter ++; 
      printf("Producer: "); 
      print_buffer(counter); 
     } 

     sleep(1); 
     pthread_mutex_unlock(&mutex); 
     sem_post(full); 
    } 
} 

void* consumer(void* var) { 
    int item; 
    while(1) { 
     sem_wait(full); 
     pthread_mutex_lock(&mutex); 

     while (counter == 0) 
      ; // waiting 

     if(counter > 0) { 
      counter --; 
      print_buffer(counter); 
     } 

     sleep(1); 

     pthread_mutex_unlock(&mutex); 
     sem_post(empty); 
    } 
} 

int main(int argc, char *argv[]) { 
    pthread_mutex_init(&mutex, NULL); 
    empty = sem_open("/mysem", O_CREAT, 0644, BUFFER_SIZE); 
    full = sem_open("/mysem", O_CREAT, 0644, 0); 

    pthread_create(&pro_thread, NULL, producer, NULL); 
    pthread_create(&con_thread, NULL, consumer, NULL); 

    pthread_exit(NULL); 

    return 0; 
} 
+0

你是否有意使用相同的信號量('/ mysem')完整和空?這在邏輯上看起來不正確。 – kaylum

+0

我不知道信號量的文件在哪裏,所以我在網上搜索,一個例子說/ mysem將存儲信號量。我不確定文件應該是什麼。 – Helen

+2

也許你應該回去閱讀[sem_open手冊頁](http://linux.die.net/man/3/sem_open)。它回答了你迄今爲止提出的問題。特別是,打開同名的信號量會產生相同的信號量。這不是你想要的這個程序。相反,你可能想要例如打開一個「/ full_sem」而打開另一個「/ empty_sem」。 – kaylum

回答

1

正如sem_open man page說:

的信號由名稱標識。

因爲你的代碼提供相同的名稱值(/mysem)兩個sem_open調用它會導致引用相同的信號可同時支持完全空。這顯然不是該計劃的邏輯應該是什麼。相反,爲每個打開不同的信號量。檢查所有函數調用的返回值也是最佳做法。

empty = sem_open("/empty_sem", O_CREAT, 0644, BUFFER_SIZE); 
if (empty == SEM_FAILED) { 
    perror("Failed to open semphore for empty"); 
    exit(-1); 
} 

full = sem_open("/full_sem", O_CREAT, 0644, 0); 
if (full == SEM_FAILED) { 
    sem_close(empty); 
    perror("Failed to open semphore for full"); 
    exit(-1); 
} 
+0

每次運行代碼時都會創建空信號和全信號嗎?因爲今天我運行的代碼和代碼什麼也沒有打印,如果我將信號名稱改爲'/ empty'和'/ full',代碼將正確運行。它可以被編譯。 – Helen

+0

我只是使用'sem_unlink'來防止名稱被使用。有用。 – Helen