2017-04-15 7 views
0

C에서 다중 스레드 스도쿠 솔루션 유효성 검사기를 작성하는 프로젝트 (숙제가 아님)로 작업하고 있습니다. C 언어에 익숙하지 않아서 코드 품질이 나쁘다고 변명했습니다. 개선.새 스레드에서 호출하는 메소드 C

9 개의 별도 스레드에서 row_check 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

두 변수를 저장하고 스레드 루틴이 구조 파스하는 구조를 사용할 수 있습니다. 배열 이름 만 전달 하시겠습니까? 즉 문자열입니까, 아니면 배열의 값으로 무엇인가를 하시겠습니까? – Gaurav

+1

'pthread_join'에 대한 매뉴얼을 읽으십시오. 여러분이'for' 루프에서'row_check'를 호출했을 때와 같기 때문입니다. 'pthread_join'은 쓰레드가 끝날 때까지 기다리므로이 쓰레드는 동시에 실행되지 않고 하나씩 실행됩니다. 또한'row_check' ('j-1')의'report'에 전달 된 세 번째 인수는'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 *'를 (를) typecasting해야하는지 확실하지 않습니다. 하지만 나중에 확인하고 필요할 경우 수정합니다. –

+0

귀하의 의견을 통해 알려주십시오. 부디. 나는 또한 그것에 대해 알고 싶어합니다. Thx. – Gaurav