2015-06-15 28 views
1

我正在尝试在C语言中为学校的任务创建一个火车站模拟。这是一个了解线程编程的练习。这里是我当前的代码:pthread_create启动例程不执行

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

void *train_function(void *args) { 
    printf("Train created!\n"); 
    pthread_exit(0); 
} 

int main() { 
    FILE *ptr_file; 
    char buff[10]; 
    int ch; 
    int train_count = 0; 

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

    if (!ptr_file) 
     return 0; 

    /* Count number of trains */ 
    while(!feof(ptr_file)) 
    { 
     ch = fgetc(ptr_file); 
     if(ch == '\n') 
     { 
      train_count++; 
     } 
    } 
    pthread_t trains[train_count]; 

    /* Create train for each line of file */ 
    int train_index = 0; 
    while (fgets(buff,10, ptr_file)!=NULL) { 
     pthread_create(&trains[train_index], NULL, train_function, NULL); 
     train_index++; 
    } 
    fclose(ptr_file); 

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

的代码读取有关从文件trains.txt火车的信息和文件(每列车)的每一行创建一个新的线程。

e:10,6 
W:5,7 
E:3,10 

我希望输出为“Train Created!”三次。编译代码会产生分段错误。我错过了什么?

+0

尝试void train_function(void * args)而不是 – Thomas

+0

使用调试器来找出seg故障发生的位置。至少应该防止“列车”阵列溢出。你认为你的逻辑是正确的,并且'train_count'被正确设置。这是一个危险的假设,并且健壮的代码至少可以抵御'fgets'循环。 – kaylum

回答

3
while (fgets(buff,10, ptr_file)!=NULL) { 
     pthread_create(&trains[train_index], NULL, train_function, NULL); 
     train_index++; 
    } 

在这里,你再次读取该文件但既然您已经阅读这个while循环之前,整个文件的文件指针已经在文件的结尾。所以你根本没有创建任何线程,但后来试图用加入(pthread_join调用)与不存在的线程。这是未定义的行为。你只需要在for循环使用train_count和创建线程:

for (int x = 0; x < train_count; x++) { 
    pthread_create(&trains[x], NULL, train_function, NULL); 
} 

此外,公告称,文件读取部是有缺陷的:

while(!feof(ptr_file)) {...} 

固定它见Why is “while (!feof (file))” always wrong?

1

代码有几个小问题。

以下代码消除了在发布代码中未使用的语句。

请勿使用feof()作为循环控件。由于几个原因,它作为一个循环控制失败。

将必要的错误检查添加到代码中。

通知正确的错误消息的适当的输出,以通过使用PERROR()函数

通知适当的错误通过使用出射的出射()函数

通知适当的标准错误 主要退出,最后通过使用return()函数

以下代码已经过测试并能够正常工作。

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

void *train_function(void *args __attribute__((unused))) 
{ 
    printf("Train created!\n"); 
    pthread_exit(0); 
} 

int main() 
{ 
    FILE *ptr_file; 
    int ch; 
    int train_count = 0; 

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

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

    // implied else, fopen successful 

    /* Count number of trains */ 
    while((ch = fgetc(ptr_file)) != EOF) 
    { 
     if(ch == '\n') 
     { 
      train_count++; 
     } 
    } 
    pthread_t trains[train_count]; 

    /* Create train for each line of file */ 
    int train_index = 0; 
    for (train_index = 0; train_index < train_count; train_index++) 
    { 
     if(pthread_create(&trains[train_index], NULL, train_function, NULL)) 
     { // then pthread_create failed 
      perror("pthread_create failed"); 
      exit(EXIT_FAILURE); // this will cause all threads to also exit 
     } 

     // implied else, pthread_create successful 
    } 

    fclose(ptr_file); 

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

对于想要学习C的人来说,这是一个很好的建议。谢谢。 – CaddyShack