使用sem_open初始化信号量

时间:2016-04-20 20:55:06

标签: c

在我的制作人和消费者问题中,我使用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;
}

1 个答案:

答案 0 :(得分:1)

sem_open man page中所述:

  

信号量通过名称识别。

由于您的代码为/mysem个调用提供了相同的名称值(sem_open),因此会导致为full和empty引用相同的信号量。这显然不是该计划的逻辑应该是什么。相反,为每个信号打开不同的信号量。检查所有函数调用的返回值也是最佳做法。

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);
}