2017-10-05 47 views
0

我正在處理此問題:從命令行獲取一個字母和相同文件的名稱,計算每個文件中char的出現次數,每個文件使用一個線程,以及打印出現的總次數。使用線程和互斥對文件計數char

這是我的代碼:

typedef struct _CharFile{ 

    char c; 
    char *fileName; 

} CharFile; 

pthread_mutex_t count = PTHREAD_MUTEX_INITIALIZER; 
int sum = 0; 

void *CountFile(void *threadarg); 

int main(int argc, const char * argv[]) { 

    pthread_t threads[argc-2]; 
    int chck, t; 
    CharFile cf; 

    for (t=0 ; t<argc-2 ; t++){ 

     cf.c = argv[1][0]; 
     cf.fileName = (char *)argv[t + 2]; 

     chck = pthread_create(&threads[t], NULL, CountFile, (void *) &cf); 
     if (chck){ 
      printf("ERROR; return code from pthread_create() is %d\n", chck); 
      exit(-1); 
     } 

    } 

    printf("%lld occurrences of the letter %c in %lld threads\n", (long long)sum, argv[1][0], (long long)argc-2); 

    return 0; 
} 

void *CountFile(void *threadarg){ 

    FILE *in; 
    CharFile *cf; 
    char c; 
    int counter = 0; 

    cf = (CharFile *) threadarg; 
    in = fopen(cf->fileName, "r"); 

    if (in == NULL){ 

     perror("Error opening the file!\n"); 
     pthread_exit(NULL); 

    } 

    while (fscanf(in, "%c", &c) != EOF){ 

     if(c == cf->c){ 

      counter += 1; 

     } 

    } 

    fclose(in); 

    pthread_mutex_lock(&count); 
    sum += counter; 
    pthread_mutex_unlock(&count); 

    pthread_exit(NULL); 
} 

我沒有得到任何錯誤的文件打開或線程創建的,但我的輸出總是0作爲總的發生。我也嘗試在線程中打印counter,並且我在每個線程中都得到了相同的數字,即使我的輸入文件不同。我錯誤地使用互斥鎖還是存在其他錯誤?

這是我的輸出中的一個:

61 occurrences of e in this thread 
0 occurrences of the letter e in 3 threads 
61 occurrences of e in this thread 
61 occurrences of e in this thread 
Program ended with exit code: 9 
+1

您不必等待您的線程完成。 –

+0

我該怎麼做? –

+1

但是你想要。通常最糟糕的方式是使用'pthread_join'。但這很簡單,你應該首先學習。 –

回答

0

有在這裏打球的幾個線程問題。

1)主線程將異步地繼續產生新線程。鑑於代碼,很可能主線程將在CountFile線程完成之前完成並退出。在Linux上,當主線程返回時,C運行庫將執行一個exit_group系統調用,它將終止所有線程。

您需要添加一些檢查以確保CountFile線程完成了相關的工作部分。在這個例子中,看看在主線程中使用pthread_join()。

2)主線程中的'cf'存儲是一個堆棧局部變量,它通過指針傳遞給每個線程。但是,由於它是相同的存儲,因此可能會發生幾種類型的故障。 a)工作線程正在訪問時,主線程可以更新工作單元。 b)相同的工作單元被髮送到多個/所有線程。

您可以通過以下幾種方式解決:'cf'可以是每個線程的CharFile數組。或'cf'可以爲每個線程動態分配。前者具有更高的性能和內存效率,但後者在結構上可能更好。特別是那個主線程將本地堆棧空間中的地址提供給另一個線程。

3)一旦項目#1被尋址並且線程在主線程printf之前退出,互斥量的使用就沒有問題。但是最好將pthread_mutex_locks放在'sum'的主線程訪問中。考慮到這個代碼可能沒有必要,但未來的代碼重構可能會改變這一點。