2016-10-02 5 views
0

現在、コマンドで送信されたテキストファイル内の文字の発生回数をカウントするためにpthreadsを使用したマルチスレッドを使用するCプログラムを作成しようとしています64KBのバッファを使用しています。私は8つのスレッドの8つのパーティションにファイルを分割します。私はCとマルチスレッドにはかなり新しいので、これは私の頭の中の方法です。C pthreadを使用してテキストファイルの文字数をカウントするマルチスレッドプログラム

プログラムは文字をカウントしていますが、正しくはありません。実行するたびに結果が異なります。ここに私のコードは、あなただけがすべてのスレッドに渡す1つのbufferPartition構造を有している(更新)

#include <pthread.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 

#define BUFFER_SIZE 65536 
#define NUMBER_OF_THREADS 8 
#define NUM_CHARS 127 


int charCount[NUM_CHARS + 1][8]; 

void* countChar(void *arg); 

struct bufferPartition { 
    unsigned char* start; 
    int size; 
    int index; 
}; 

int main(int argc, char *argv[]){ 
    pthread_t tid[NUMBER_OF_THREADS]; 
    pthread_attr_t attr[NUMBER_OF_THREADS]; 
    size_t fileSize; 
    unsigned char* buffer = (unsigned char *) malloc(BUFFER_SIZE); 
    unsigned int bufferPartitionSize; 

    printf("%i", argc); 
    if(argc != 2){ 
     fprintf(stderr,"usage: a.out <integer value>\n"); 
     return -1; 
    } 

    FILE* fp = fopen(argv[1], "r+"); 

    if(fp == NULL){ 
     printf("Error! Could not open the file."); 
     return -1; 
    } 
    fileSize = fread(buffer, 1, BUFFER_SIZE,fp); 

    fclose(fp); 

    if(fileSize % 8 != 0){ 
     bufferPartitionSize = ((8 - (fileSize % 8)) + fileSize)/8; 
    }else{ 
     bufferPartitionSize = fileSize/8; 
    } 

    for(int index = 0; index < NUMBER_OF_THREADS; index++){ 

     struct bufferPartition* bufferPartition = (struct bufferPartition*)malloc(sizeof(struct bufferPartition)); 

     bufferPartition -> size = bufferPartitionSize; 
     bufferPartition -> start = buffer + (index * (bufferPartition -> size)); 
     bufferPartition -> index = index + 1; 

     pthread_attr_init(&attr[index]); 
     pthread_create(&tid[index], &attr[index], countChar, bufferPartition); 
    } 

    for(int index = 0; index <= NUMBER_OF_THREADS; index++){ 
     pthread_join(tid[index], NULL); 
    } 

    for(unsigned int i = 0; i <= 128; i++){ 

     for(unsigned int k = 1; k <= NUMBER_OF_THREADS; k++){ 
      charCount[i][0] += charCount[i][k]; 
     } 
     if(i < 32){ 
      printf("%i occurrences of 0x%x\n", charCount[i][0], i); 
     }else{ 
      printf("%i occurrences of %c\n",charCount[i][0], i); 
     } 
    } 
    return 0; 
} 

void* countChar(void *arg){ 

    struct bufferPartition* bufferPartition = (struct bufferPartition*) arg; 
    unsigned int character; 
    int threadNumber = bufferPartition->index; 

    for(int index = 0; index < bufferPartition -> size; index++){ 

     character = bufferPartition -> start[index]; 
     (charCount[character][threadNumber])++; 
    } 
} 
+0

コードで未定義の動作が発生する可能性があります。文字の範囲は、システムのデフォルト文字が署名されていない場合は '0'から' 255'、システムのデフォルト文字タイプが署名されている場合は '-128'から' 127'になります。どちらもコードの許容範囲の「0」から「127」の範囲外になる可能性があります。最も簡単な解決策は、あなたのバッファに 'unsigned char *'を使い、 'charCount'配列の要素数に' UCHAR_MAX + 1'を使うことです: 'int charCount [UCHAR_MAX + 1] [NUMBER_OF_THREADS];' charからの変換が符号拡張されていると、int型の符号付きではさらに悪化する可能性があります。 –

+0

入手しました。私はそれをして、コードはまだファイルにない文字を数えています。 –

+0

あなたは 'file_size'のために何を得ていますか?更新されたコードを投稿できますか? –

答えて

1

です。つまり、それらがすべて単一の構造を共有することを意味し、単一の構造のメンバーを変更すると、すべてのスレッドがその構造を使用します。

スレッドごとに1つの構造体を割り当てる必要があります。

+0

素晴らしいですね。ありがとうございました! –

関連する問題