消费者和生产者使用信号量

时间:2013-03-29 06:36:30

标签: c semaphore producer-consumer

我目前遇到死锁和核心转储。

在主要之外我有以下

char buffer[SLOTCOUNT][SLOTSIZE];
int isEmpty[SLOTCOUNT]; 

FILE *myInFile;
FILE *myOutFile;

sem_t buf_lock, slot_avail, item_avail;

主要内部我有

int main(int argc, const char * argv[]){
    //Create the basics of threads and intilize the sem
    pthread_t consumer_t, producer_t;

    sem_init(&buf_lock, 0, 1);
    sem_init(&slot_avail, 0, 4); 
    sem_init(&item_avail, 0, 0);

    /*Clear and clean the buffer*/
    for(int i=0; i <= SLOTCOUNT; ++i){
        isEmpty[i] = 0;
        for(int j=0; j <= SLOTSIZE; ++j){
            buffer[i][j] = NULL;
        }
    }

    /*Check to make sure that the correct number of inputs have been provided*/
    checkStart(argc);

    /*Get the locations to the files and save it into a local variable. */
    char inFile[sizeof(argv[1])];
    char outFile[sizeof(argv[2])];
    strcpy(inFile, argv[1]);
    strcpy(outFile, argv[2]);

    /*Load the file to read from and create the file to write to*/
    fileReady(inFile, outFile);

    /*Get the threads ready to return*/
    pthread_create(&producer_t, NULL, producer, NULL);
    pthread_create(&consumer_t, NULL, consumer, NULL);
    pthread_join(producer_t, NULL);
    pthread_join(consumer_t, NULL);


    return 0;
}

最后,我的制作人函数

void* producer(){

/*Critical Section*/
    sem_wait(&slot_avail);
    printf("gets here\n");
    sem_wait(&buf_lock);
    printf("Never gets here\n");
    for (int i = 0; i <= SLOTCOUNT; ++i){
        if(buffer[i][0] == NULL) fread(buffer[i], sizeof(char), READSIZE, myInFile);
    }
    sem_post(&buf_lock);
    sem_post(&item_avail);

/*Critical Section*/

}

目前,printf(“永远不会到达这里”)从不打印。

我想解决这个问题。

但是,如果我注释掉sem_wait(&buf_lock),它会打印出来,然后是核心转储。

任何想法我做错了或如何调试核心转储

编辑:我知道这不是问题的最佳解决方案,但这只是为了表明对信号量的理解。

编辑:其余代码已经过独立测试,可以正常运行。 IE的大小......等等。

我也试过

int errno = sem_wait(&buf_lock);
printf("%s", strerror(errno));

看看有什么事情发生,但它仍然锁定,正如预期的那样,印刷品不会印刷。

1 个答案:

答案 0 :(得分:2)

切勿在不测试其返回值的情况下使用此类库例程。特别是,当存在中断时(例如,IO),sem_wait可能会返回。阅读相应的手册页,了解所有函数的可能返回值以及它们如何返回错误。

通常,POSIX信号量不是使用线程进行应用程序编程的正确工具。首先,它们只是所有POSIX系统都不支持的扩展,然后真正预见作为线程间控制的基本工具的工具是pthread_mutex_tptread_cond_t

此外,您的生产者函数规范是错误的,您的编译器不应该在没有咆哮的情况下接受它。系统将使用参数调用此函数,因此您在此处具有未定义的行为。不要这样做,即使你不需要线程函数接收的void*参数,你也需要声明该参数。

另一个小的挑剔:以_t结尾的名称由POSIX保留用于将来的扩展。他们通常指的是类型。不要将它们用于变量。