Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 在多个线程之间共享变量_C_Multithreading_Pthreads - Fatal编程技术网

C 在多个线程之间共享变量

C 在多个线程之间共享变量,c,multithreading,pthreads,C,Multithreading,Pthreads,我正在模拟一个火车站。列车信息从文件中读取。文件的每一行表示一列,每一列都有自己的线程。火车站的正线一次只能容纳1列火车。这是我的密码: #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <string.h> #include <readline/readline.h> #include <unistd.h> pthread_mutex

我正在模拟一个火车站。列车信息从文件中读取。文件的每一行表示一列,每一列都有自己的线程。火车站的正线一次只能容纳1列火车。这是我的密码:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <readline/readline.h>
#include <unistd.h>

pthread_mutex_t main_track_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t  main_track_condition_var = PTHREAD_COND_INITIALIZER;
int main_track_status = 0;

void *train_function(void *args) {
    /* Parse train information */
    int line_number = atoi(strtok(args, ":,"));
    char *priority_direction = strtok(NULL,":,");
    int loading_time = atoi(strtok(NULL, ":,"));
    int crossing_time = atoi(strtok(NULL, ":,"));

    /* Load train */
    sleep(loading_time/10);
    printf("Train %d is ready to go %s\n",line_number,priority_direction);

    /* If the main track is currently in use, wait for it to become available */
    while(main_track_status)
        pthread_cond_wait(&main_track_condition_var, &main_track_mutex);

    /* Use the main track */
    pthread_mutex_lock(&main_track_mutex);
    main_track_status = 1;
    printf("Train %d is ON the main track going %s\n",line_number,priority_direction);
    sleep(crossing_time/10);
    main_track_status = 0;

    /* Notify other trains main track is empty */
    pthread_mutex_unlock(&main_track_mutex);
    pthread_cond_signal(&main_track_condition_var);
    printf("Train %d is OFF the main track after going %s\n",line_number,priority_direction);

    pthread_exit(0);
}

int main() {
    FILE *ptr_file;
    char buff[10];
    int train_count = 0;
    char *train;
    char line[15];
    pthread_t trains[3];

    ptr_file = fopen("./trains.txt", "r");

    if (!ptr_file) 
    {
        perror("fopen for trains.txt failed");
        exit(EXIT_FAILURE);
    }

    /* Create train for each line of file */
    while (fgets(buff,10, ptr_file)!=NULL) {
        train = (char*)malloc(10 * sizeof(char));

        /* Include line number from file in train information */
        sprintf(line, "%d:", train_count);  
        strcat(line, buff);
        strcpy(train, line);

        if(pthread_create(&trains[train_count], NULL, &train_function, (void *) train))
        {
            perror("pthread create failed");
            exit(EXIT_FAILURE);
        }
        train_count++;
    }
    fclose(ptr_file);

    /* Wait for all trains to leave the station */
    for (int x = 0; x < train_count; x++) {
        pthread_join(trains[x], NULL);
    }

    free(train);
    exit(EXIT_SUCCESS);
}
程序的输出为:

Train 1 is ready to go W
Train 1 is ON the main track going W
Train 1 is OFF the main track after going W
Train 2 is ready to go E
Train 2 is ON the main track going E
Train 0 is ready to go e
Train 2 is OFF the main track after going E

我认为我的错误在于列车功能。正如你所看到的,0次列车永远无法进入正线。我一定是误解了线程是如何被条件变量唤醒并陷入死锁的。我遗漏了什么?

是的,您对
pthread\u cond\u wait
有一点误解。报告说:

pthread_cond_timedwait()和pthread_cond_wait()函数应 条件变量上的块。它们应在互斥锁锁定的情况下调用 通过调用线程或未定义的行为结果

这些函数以原子方式释放互斥,并导致调用线程 阻止条件变量cond

因此,您需要在调用
pthread\u cond\u wait
之前锁定。也就是说,您的代码应该是:

/* If the main track is currently in use, wait for it to become available */
pthread_mutex_lock(&main_track_mutex); /* SHOULD LOCK HERE */
while(main_track_status)
    pthread_cond_wait(&main_track_condition_var, &main_track_mutex);

/* Use the main track */
//pthread_mutex_lock(&main_track_mutex); /* INCORRECT */
//<..SNIP..>
pthread_mutex_unlock(&main_track_mutex);
pthread_cond_signal(&main_track_condition_var);
/*如果主轨道当前正在使用,请等待它可用*/
pthread_mutex_lock(&main_track_mutex);/*应该锁在这里*/
while(主轨道状态)
pthread_cond_wait(&main_track_condition_var,&main_track_mutex);
/*使用主轨道*/
//pthread_mutex_lock(&main_track_mutex);/*不正确*/
//
pthread_mutex_unlock(&main_track_mutex);
pthread_cond_信号(&main_track_condition_var);

是的,您对
pthread\u cond\u wait
有一点误解。报告说:

pthread_cond_timedwait()和pthread_cond_wait()函数应 条件变量上的块。它们应在互斥锁锁定的情况下调用 通过调用线程或未定义的行为结果

这些函数以原子方式释放互斥,并导致调用线程 阻止条件变量cond

因此,您需要在调用
pthread\u cond\u wait
之前锁定。也就是说,您的代码应该是:

/* If the main track is currently in use, wait for it to become available */
pthread_mutex_lock(&main_track_mutex); /* SHOULD LOCK HERE */
while(main_track_status)
    pthread_cond_wait(&main_track_condition_var, &main_track_mutex);

/* Use the main track */
//pthread_mutex_lock(&main_track_mutex); /* INCORRECT */
//<..SNIP..>
pthread_mutex_unlock(&main_track_mutex);
pthread_cond_signal(&main_track_condition_var);
/*如果主轨道当前正在使用,请等待它可用*/
pthread_mutex_lock(&main_track_mutex);/*应该锁在这里*/
while(主轨道状态)
pthread_cond_wait(&main_track_condition_var,&main_track_mutex);
/*使用主轨道*/
//pthread_mutex_lock(&main_track_mutex);/*不正确*/
//
pthread_mutex_unlock(&main_track_mutex);
pthread_cond_信号(&main_track_condition_var);

是的,您对
pthread\u cond\u wait
有一点误解。报告说:

pthread_cond_timedwait()和pthread_cond_wait()函数应 条件变量上的块。它们应在互斥锁锁定的情况下调用 通过调用线程或未定义的行为结果

这些函数以原子方式释放互斥,并导致调用线程 阻止条件变量cond

因此,您需要在调用
pthread\u cond\u wait
之前锁定。也就是说,您的代码应该是:

/* If the main track is currently in use, wait for it to become available */
pthread_mutex_lock(&main_track_mutex); /* SHOULD LOCK HERE */
while(main_track_status)
    pthread_cond_wait(&main_track_condition_var, &main_track_mutex);

/* Use the main track */
//pthread_mutex_lock(&main_track_mutex); /* INCORRECT */
//<..SNIP..>
pthread_mutex_unlock(&main_track_mutex);
pthread_cond_signal(&main_track_condition_var);
/*如果主轨道当前正在使用,请等待它可用*/
pthread_mutex_lock(&main_track_mutex);/*应该锁在这里*/
while(主轨道状态)
pthread_cond_wait(&main_track_condition_var,&main_track_mutex);
/*使用主轨道*/
//pthread_mutex_lock(&main_track_mutex);/*不正确*/
//
pthread_mutex_unlock(&main_track_mutex);
pthread_cond_信号(&main_track_condition_var);

是的,您对
pthread\u cond\u wait
有一点误解。报告说:

pthread_cond_timedwait()和pthread_cond_wait()函数应 条件变量上的块。它们应在互斥锁锁定的情况下调用 通过调用线程或未定义的行为结果

这些函数以原子方式释放互斥,并导致调用线程 阻止条件变量cond

因此,您需要在调用
pthread\u cond\u wait
之前锁定。也就是说,您的代码应该是:

/* If the main track is currently in use, wait for it to become available */
pthread_mutex_lock(&main_track_mutex); /* SHOULD LOCK HERE */
while(main_track_status)
    pthread_cond_wait(&main_track_condition_var, &main_track_mutex);

/* Use the main track */
//pthread_mutex_lock(&main_track_mutex); /* INCORRECT */
//<..SNIP..>
pthread_mutex_unlock(&main_track_mutex);
pthread_cond_signal(&main_track_condition_var);
/*如果主轨道当前正在使用,请等待它可用*/
pthread_mutex_lock(&main_track_mutex);/*应该锁在这里*/
while(主轨道状态)
pthread_cond_wait(&main_track_condition_var,&main_track_mutex);
/*使用主轨道*/
//pthread_mutex_lock(&main_track_mutex);/*不正确*/
//
pthread_mutex_unlock(&main_track_mutex);
pthread_cond_信号(&main_track_condition_var);

有什么帮助吗?正如这里所解释的,我认为您应该先锁定互斥锁,然后等待条件是否有帮助?正如这里所解释的,我认为您应该先锁定互斥锁,然后等待条件是否有帮助?正如这里所解释的,我认为您应该先锁定互斥锁,然后等待条件是否有帮助?正如这里所解释的,我认为您应该先锁定互斥锁,然后等待条件。我将确保更仔细地阅读手册页。谢谢。你最好在解锁互斥锁之前从关键部分发出信号。我会确保更仔细地阅读手册页。谢谢。你最好在解锁互斥锁之前从关键部分发出信号。我会确保更仔细地阅读手册页。谢谢。你最好在解锁互斥锁之前从关键部分发出信号。我会确保更仔细地阅读手册页。谢谢。您最好在解锁互斥锁之前,从关键部分内部发出信号。