2017-03-23 3 views
1

pthread와 마스터 - 슬레이브 모델을 사용하여 Buddhabrot 프랙탈과 병렬로 pgm 이미지를 생성하려고합니다. 테스트에서 프로그램이 올바른 병렬 모드로 모델을 시작하지만 무한 루프 내부에있는 것으로 보입니다. 문제는 어느 것이 문제인지를 볼 수 없다는 것입니다. 누군가가 내게 그것에 대해 빛을 줄 수 있습니까? 고맙습니다. 그것은 문제처럼 보인다pthread가있는 Buddhabrot 프랙탈

#include <pthread.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <assert.h> 
#include <math.h> 
#define N_SLAVES 3 

double next = -1; 


int i = 0, nColumns = 2048, nLines = 2048, ite = 600; 
double y, dt = 0.001; 


int completedIterations; 

pthread_mutex_t mutex; 
pthread_cond_t condM; 
pthread_cond_t condE; 

typedef struct { 
    int x; 
    int y; 
} int2; 
typedef struct{ 
    double x; 
    double y; 
} double2; 

int2 coordinatesConversion(double x,double y, int nColumns,int nLines){ 

    int2 ret; 
    int2 retError; 
    retError.x=-1; 
    retError.y=-1; 

    ret.x=round(((2.0+x)/3.5) *((double)(nColumns-1))); 
    ret.y=round(((1.5+y)/3.5) *((double)(nLines-1))); 

    if(ret.x<0 || ret.x>=nColumns) return retError; 
    if(ret.y<0 || ret.y>=nLines) return retError; 

    return ret; 
} 

int printMatrixToFilePGM(float **mat,int tamx, int nLines, char *srcFile){ 

    printf("First\n"); 

    FILE *arq=fopen(srcFile,"w"); 

    int cont, cont2; 
    float min,max; 
    min=mat[0][0]; 
    max=mat[0][0]; 
    for(cont=0;cont<nLines;cont++){ 
     for(cont2=0;cont2<tamx;cont2++){ 
      if(min>mat[cont][cont2]) min=mat[cont][cont2]; 
      if(max<mat[cont][cont2]) max=mat[cont][cont2]; 
     } 
    } 
    max=max*0.35; 
    float delta=max-min; 
    fprintf(arq,"P2 \n"); 
    fprintf(arq,"#something \n"); 
    fprintf(arq,"%d\n%d \n",tamx,nLines); 
    fprintf(arq,"255\n"); 
    for(cont=0;cont<nLines;cont++){ 
     for(cont2=0;cont2<tamx;cont2++){ 
      int valpixel=((mat[cont][cont2]-min)/delta)*255.0f; 
      if(valpixel>255) valpixel=255; 
      fprintf(arq,"%d \n", valpixel); 
     } 
    } 
    fclose(arq); 
} 

float** mallocFloatMatrix(int tamx, int nLines, float defaultValueOfTheElementsAtMatrix){ 

    float **errorCodeReturn=0x0; 
    float **mat; 
    int i,j; 
    int condErrorMalloc=0; 
    mat=malloc(sizeof(float *)*nLines); 
    if(mat==0x0) return errorCodeReturn; 
    for(i=0;i<tamx;i++) 
     mat[i]=malloc(sizeof(float)*tamx); 


    for(i=0;i<tamx;i++){ 
     if(mat[i]==0x0){ 
      condErrorMalloc=1; 
      break; 
     } 
    } 

    if(condErrorMalloc==0){ 
     return mat; 
    } 
    for(i=0;i<nLines;i++){ 
     for(j=0;j<tamx;j++) 
      mat[i][j]=defaultValueOfTheElementsAtMatrix; 
    } 
    for(i=0;i<tamx;i++) 
     if(mat[i]!=0x0) free(mat[i]); 

    free(mat); 

    return errorCodeReturn; 
} 

void freeFloatMatrix(float **mat,int tamx, int nLines){ 
    int i; 
    for(i=0;i<nLines;i++){ 
     if(mat[i]!=0x0) free(mat[i]); 
    } 
    free(mat); 
} 

int iteration(double x,double y, int nColumns,int nLines, int ite,int2 *iterationPath){ 

    int cont;  
    int condInvalidPointer=1; 
    double2 z; 
    z.x=0.0; 
    z.y=0.0; 
    double2 c; 
    c.x=x; 
    c.y=y; 
    double2 zt; 

    for(cont=0;cont<ite;cont++){ 
     zt.x=((z.x*z.x)-(z.y*z.y))+c.x; 
     zt.y=(2.0*(z.x*z.y))+c.y; 
     z=zt; 
     if(((z.x*z.x)+(z.y*z.y))>4.0){ 
      if(cont>100) 
       condInvalidPointer=0; 
      break; 
     } 
     iterationPath[cont]=coordinatesConversion(z.x,z.y,nColumns,nLines); 
    } 
    if(condInvalidPointer) 
     return 0; 

    return cont; 
} 

void *master(void *param){ 
    printf("Second\n"); 
    int size = round(4.0/dt); 
    int i; 
    int progress = 0; 
    for(i = 0; i < size; i++){ 
     next = -2.0+i*dt; 
     pthread_mutex_lock(&mutex); 
     pthread_cond_signal(&condE); 
     pthread_cond_wait(&condM, &mutex); 
     pthread_mutex_unlock(&mutex); 

    //  progress++; 
    //  if(progress%100 ==0)//print at screen information about progrees of the operation 
    //   printf("2 - %lf \n", next); 
    } 
} 


void *slave(void *param){ 
    int size = round(4.0/dt); 
    printf("Third\n"); 
    int k; 
    float **mat = mallocFloatMatrix(nColumns, nLines, 0.0f); 

    if(mat == 0x0) return 0; 


    while(1){ 

     pthread_mutex_lock(&mutex); 
     if(i >= size){ 
      pthread_mutex_unlock(&mutex); 
      pthread_exit(0); 

     } 
     i++; 
     while(next == -1){ 
      pthread_cond_signal(&condM); 
      pthread_cond_wait(&condE, &mutex); 

     } 

     double x = next; 


     next = -1; 

     pthread_cond_signal(&condM); 
     pthread_mutex_unlock(&mutex); 


     for(y=-2.0;y<2.0;y=y+dt){ 
      int2* iterationPath = (int2 *)malloc(sizeof(int2) * ite); 
      if(iterationPath==0x0) return 0x0; 

      completedIterations = iteration(x, y, nColumns, nLines, ite, iterationPath); 



      for(k = 0; k < completedIterations; k++){ 
       if(iterationPath[k].x!=-1 && iterationPath[k].y!=-1)//test if a point z in the iteration k may be normalized to coordinates at matrix mat. 
        mat[iterationPath[k].x][iterationPath[k].y] = mat[iterationPath[k].x][iterationPath[k].y]+1.0f;//increments a point in matrix, this point is pointed by z with z points normalized. 


      } 

      free(iterationPath); 

     } 

    } 
    printMatrixToFilePGM(mat,nColumns,nLines,"saida3.pgm"); 
    freeFloatMatrix(mat,nColumns,nLines); 
} 



int main(void){ 

    printf("Main\n"); 

    int i, j, k; 

    pthread_t master_t; 
    pthread_t slave_t[N_SLAVES]; 

    pthread_create(&master_t, NULL, master, NULL); 

    for(i = 0; i < N_SLAVES; i++) 
     pthread_create(&slave_t[i], NULL, slave, NULL); 

    pthread_exit(0); 

    return 0; 
} 

답변

1

는 "아직 마스터에 의해 초기화되지"의미 next에 매직 넘버로 -1를 할당하는 것입니다. 이 같은 next를 계산하기 때문에, 그것은 가능한 정당한 값은 다음과 같습니다 dt는 0.001

next = -2.0+i*dt; 

때문에, nexti 1000 때 -1로 동일하고, 것 4000-i 루프 (4.0/dt) 이후, 그것을 루프가 종료되기 전에 발생합니다. 그런 다음 슬레이브 쓰레드가 -1이 아닌 다른 값을 기다리고 있으므로 condM을 절대 설정하지 않으므로 pthread_cond_wait(&condM, &mutex);이 절대 반환되지 않으므로 i은 절대 증가하지 않습니다.

마법 번호를 -1에서 next (예 : -100)의 가능한 값 범위를 벗어난 값으로 변경하거나 다른 메커니즘을 사용하십시오.

관련 문제