在多个线程之间共享变量
Posted
技术标签:
【中文标题】在多个线程之间共享变量【英文标题】:Share variable between multiple threads 【发布时间】:2015-06-17 22:09:58 【问题描述】:我正在创建一个火车站的模拟。从文件中读取列车信息。文件的每一行代表一列火车,每列火车都有自己的线程。火车站的主轨道一次只能停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);
火车输入文件:
e:10,6
W:5,7
E:3,10
程序的输出是:
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
我认为我的错误在于 train_function。如您所见,火车 0 永远无法进入主轨道。我一定是误解了线程是如何被条件变量唤醒的,并且陷入了死锁。我错过了什么?
【问题讨论】:
this 会有帮助吗?正如那里所解释的,我认为你应该先锁定互斥锁,然后等待条件 【参考方案1】:是的,你对pthread_cond_wait
有一点误解。 man page 说:
pthread_cond_timedwait() 和 pthread_cond_wait() 函数应 阻塞条件变量。应在互斥锁锁定的情况下调用它们 由调用线程或未定义的行为结果。
这些函数原子地释放互斥体并导致调用线程 阻塞条件变量 cond;
所以你需要在调用pthread_cond_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);
【讨论】:
我会确保更仔细地阅读手册页。谢谢。 您最好从临界区内部发出信号,即在解锁互斥锁之前。以上是关于在多个线程之间共享变量的主要内容,如果未能解决你的问题,请参考以下文章