2017-10-05 7 views
0

私はこの問題に取り組んでいます:文字と同じファイルの名前をコマンドラインから取り出し、ファイルごとに1つのスレッドを使用して各ファイルの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の前に出ると、mutexの使用はokになります。しかし、pthread_mutex_locksをメインスレッドのアクセスの周りに「sum」と置く方が良いかもしれません。このコードが与えられている必要はないかもしれませんが、将来のコードリファクタがそれを変更する可能性があります。

関連する問題