1

私はマルチスレッドに不慣れで、マルチスレッドを使用して同じ当座預金口座で銀行取引をシミュレートしようとしています。各スレッドは、ファイルから実行するアクションを読み取ります。このファイルには、整数で構成される各行の操作が含まれます。メインプログラムは、パス内のファイルと同じ数のスレッドを作成する必要があります。

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

  DIR *buff;
struct dirent *dptr = NULL;
pthread_t hiloaux[MAX_THREADS];     
int  i=0,j=0, nthreads=0;
char *pathaux;


memset(hiloaux,0,sizeof(pthread_t)*MAX_THREADS);
diraux=malloc((267+strlen(argv[1]))*sizeof(char));
buff=opendir(argv[1]);
while((dptr = readdir(buff)) != NULL && nthreads<MAX_THREADS)//read files in the path
    {


    if (dptr->d_name[0]!='.'){    
        pthread_mutex_lock(&mutex_path);//mutual exclusion  
        strcpy(pathaux,argv[1]);        
        strcat (pathaux,"/");
        strcat (pathaux,dptr->d_name);//makes the route (ex:path/a.txt)

        pthread_create(&hiloaux[nthreads],NULL,readfile,(void *)pathaux);
        //creates a thread for each file in the path
                   nthreads++;
    }

}

for (j=0;j<nthreads;j++){
pthread_join(hiloaux[j],NULL);
}

  closedir(buff);
  return 0;

}

私の問題は、スレッドが正しいパス引数を受け取っていないように見えることです。ミューテックス(mutex_path)を配置しましたが、すべて同じファイルを読み取ります。関数readfile()内でこのミューテックスのロックを解除します。

void *readfile(void *arg){
FILE *fichero;
int x=0,n=0;
int suma=0; 
int cuenta2=0;


char * file_path = (char*)arg;
n=rand() % 5+1; //random number to sleep the program each time I read a file line
pthread_mutex_unlock(&mutex_path);//unlock the mutex

fichero = fopen(file_path, "r");

    while (fscanf (fichero, "%d", &x)!=EOF){

           pthread_mutex_lock(&mutex2);//mutual exclusion to protect variables(x,cuenta,cuenta2)        

         cuenta2+=x;    

          if (cuenta2<0){
        printf("count discarded\n");
          }

          else cuenta=cuenta2;      
          pthread_mutex_unlock(&mutex2);

    printf("sum= %d\n",cuenta);
    sleep(n); //Each time i read a line,i sleep the thread and let other thread read other fileline
}
 pthread_exit(NULL);
fclose(fichero);

プログラムを実行すると、この出力が得られます

alberto@ubuntu:~/Escritorio/practica3$ ./ejercicio3 path
read file-> path/fb
read -> 2
sum= 2
read file-> path/fb
read -> 2
sum= 2
read file-> path/fb
read -> 4
sum= 6
read file-> path/fb
read -> 4
sum= 6
read file-> path/fb
read -> 6
sum= 12
read file-> path/fb
read -> 6
sum= 12

うまく機能しているようで、行を読み取ってしばらくスリープします。この間、別のスレッドが機能しますが、問題は、両方のスレッドが同じファイル(path / fb)を開くことです。前に言ったように、問題はパスの引数にあると思いますが、mutex_pathが彼の仕事をしなかったようです。何が悪いのかよくわからないので、少し助けていただければ幸いです。

どうもありがとうございます。

4

2 に答える 2

0

「readfile」関数で

この線

char * file_path =(char *)arg;

ポインタを文字列メモリにコピーするだけで、メモリ自体はコピーしません。したがって、ワーカースレッドが継続している間、manスレッドによって変更される可能性があります(今後も変更されます)。

そこでメモリコピーを作成します。

または、スレッドへのすべての引数をメインスレッドの個別のメモリに格納しておくと、最初のミューテックスはまったく必要ありません。

于 2012-11-17T00:52:56.133 に答える
0

まず、pathauxにメモリを割り当てる場所がわかりません。メモリセグメンテーションではなく、strcpyまたはstrcatがどのように機能するのか疑問に思っています。C ++コンパイラでコンパイルしてみてください、それは文句を言うかもしれません。

問題に関しては、uはポインタを渡しているので、すべてのスレッドが同じ場所を指しています。正しいアプローチはreaddirループ内にあります-1。メモリを作成してパスをコピーします(ループ内で毎回メモリを作成することに注意してください)2。このメモリを新しいスレッドに渡します。このようにすると:a。ミューテックスパスを使用する必要はありません。b。readfileメソッドの最後でfreeを呼び出します。

于 2012-11-17T00:53:59.043 に答える