2017-04-15 12 views
0

私はC言語でマルチスレッドのSudokuソリューションバリデーターを構築しています(プロジェクトではありません)。改善する。新しいスレッドからメソッドを呼び出すC

私はメソッドrow_checkを9つのスレッドから9回呼び出したいと思う。パラメータとしてのメソッドの場合は、行番号(arg)と配列名(arr)を渡します。スレッドを作成しましたが、メソッドにパラメータを適切に渡す方法が不明です。誰もこれで私を助けることができますか?あなたが好きなものへのポインタ -

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


void* row_check(void* arg, int *arr) 
{ 
    int i = *((int *)arg); //trying to convert row number to int 
    int j, flag; 

    while(i < 9) 
    { 
     flag=0x0000; 

     for(j = 0; j < 9; j++) 
      flag |= 1 << (arr[i][j]-1); 

     if (flag != 0x01FF) 
      report("row", i, j-1); 
    } 

} 

void report(char *s, int i, int j) 
{ 
    printf("\nThe sudoku is INCORRECT"); 
    printf("\nin %s. Row:%d,Column:%d", s, i+1, j+1); 
    getch(); 
    exit(0); 
} 


int main(int argc, char* argv[]) 
{ 
    int i,j; 
    char arr1[9][9]; 
    FILE *file = fopen(argv[1], "r"); 

    if (file == 0) 
    { 
     fprintf(stderr, "failed"); 
     exit(1); 
    } 
     int col=0, row=0; 
     int num; 

     while(fscanf(file, "%d ", &num) == 1) 
     { 
     arr1[row][col] = num; 
     col++; 
     if(col == 9) 
     { 
      row++; 
      col = 0; 
     } 
     } 
     fclose(file); 

     pthread_t tid; 
     pthread_attr_t attr; 
     pthread_attr_init(&attr); 

     int n; 
     for(n=0; n < 9; n++) //creating 9 threads 
     { 
      pthread_create(&tid, &attr, row_check, n); 
      pthread_join(tid, NULL); 
     } 

     return 0; 
} 
+0

次の2つの変数を格納し、スレッドルーチンにその構造PASする構造を使用することができます。 配列名、つまり文字列のみを渡したいのですか、配列の値で何かしたいですか? – Gaurav

+1

'pthread_join'のマニュアルを読んでください。あなたが' for'ループで 'row_check'を呼び出したのと同じように呼び出すためです。 'pthread_join'はスレッドが終了するまで待っているので、これらのスレッドは同時に実行されません。また 'row_check'(' j-1')の 'report'に渡される3番目の引数は、' for'ループの終了後 'j'が9に等しいので常に8です。 – Rogus

+0

私は良い気分にはならないコード内のwhileループ! あなたはそれについて説明できますか? – Gaurav

答えて

0

スレッドエントリ機能はそれだけで一つのパラメータを受信する形式void *(*start_routine) (void *)、でなければなりません。

最もよく使用される手法は、スレッドエントリ関数に渡す値をstructと定義することです。その型の変数を作成し、それを初期化し、そのアドレスをスレッドエントリ関数に渡します。

例:

typedef thread_data_s 
{ 
    char *ptr; 
    int row_num; // I would prefer to define it as `unsigned int` but I stick to your example 
    // + any other data you want to pass to the thread 
} thread_data_t; 

.... 

thread_data_t data[NUM_OF_THREADS]; 

.... 

for(n=0; n < NUM_OF_THREADS; n++) //creating 9 threads 
{ 
    data[n].ptr = &arr1[n][0]; 
    data[n].row_num = n; 
    pthread_create(&tid, &attr, row_check, &data[n]); 
} 

... 

for(n=0; n < NUM_OF_THREADS; n++) // waiting for all the threads here 
{ 
    pthread_join(tid, NULL); 
} 

そして、あなたのエントリ関数は次のようになります。

void* row_check(void* data) 
{ 
    //int i = *((int *)arg); //trying to convert row number to int 
    thread_data_t *my_data_ptr = data; 
    int j, flag; 

    while(i < 9) 
    { 
     flag=0x0000; 

     for(j = 0; j < 9; j++) 
      flag |= 1u << ((my_data_ptr->ptr)[my_data_ptr->row_num][j] - 1); 
     // Shouldn't it be under the `for` loop block? If so, please add `{}` to the `for` loop 
     if (flag != 0x01FF) 
      report("row", my_data_ptr->row_num, j-1); 
    } 

    return NULL; 
} 
+0

'thread_data_t * my_data_ptr = data; – Gaurav

+0

@ GauravPathak * C *で別のポインタ型に 'void *'を型キャストする必要があるとは思えません。しかし、私は後でそれをチェックし、必要に応じて修正します。 –

+0

あなたのコメントを通じて私に教えてください。お願いします。 私はまたそれについて知りたいと思っています。 Thx。 – Gaurav

関連する問題