2

我目前正在经历死锁和核心转储。

在主要之外,我有以下内容

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("Never get here") 从不打印。

我想解决这个问题。

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

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

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

编辑:其余代码已经过独立测试并且可以正常工作。IE char 的大小...等。

我也试过

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

看看发生了什么,但它仍然锁定并且正如预期的那样打印不打印。

4

1 回答 1

2

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

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

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

另一个次要的 nitpick:以 POSIX 结尾的名称_t被保留用于将来的扩展。它们通常指类型。不要将它们用于变量。

于 2013-03-29T07:22:07.340 回答