2015-06-15 30 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