2012-05-18 116 views
1

我在使用此程序中的消息隊列時遇到問題 它應該啓動一些進程,通過命令提示符將參數傳遞給程序,但它只啓動並計算點一個過程...其他人不會發射.. 請幫助我。Mandelbrot消息隊列阻塞 - C

這是創建消息隊列並將選定數據輸出爲pgm格式的程序 只有第一個進程運行其他進程不需要 任何人都可以告訴我爲什麼?

#include <unistd.h> 
#include <stdio.h> 
#include <sys/types.h> 
#include <sys/ipc.h> 
#include <sys/msg.h> 
#include <stdlib.h> 
#include <string.h> 
void output_pgm(char *filename,double *buffer, int nx, int ny, double max) { 
    int i; 
    FILE *file; 
    file = fopen(filename,"w"); 
    fprintf(file,"P2\n"); 
    fprintf(file,"%d %d\n",nx,ny); 
    fprintf(file,"%d\n",(int)max); 
    for (i=0; i<nx*ny; i++) { 
    if (!(i%nx)) fprintf(file,"\n"); 
    fprintf(file,"%d ",(int)buffer[i]); 
    } 
    fclose(file); 
} 

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

    if(argc != 2) { 
    } else { 

     int n = atoi(argv[1]); 
     int i = 0; 
     struct msgbuf { 
       long mtype; 
     int x; 
     int y; 
     double value; 
     }; 

     struct envio { 
      long mtype; 
      long type; 
      int ny; 
      double yM1; 
      double yM2; 
     }; 


     key_t key = 123; 
     key_t key2 = 124; 
     int msgflg = IPC_CREAT | 0666; 
     int msqid = msgget(key,msgflg); 
     int msqid2 = msgget(key2,msgflg); 
     switch(fork()) { 
      case -1: 
      printf("Erro de fork"); 
      break; 
      case 0: 
      printf("Oi: %d\n",n);   
      double *b; 
      int x,y,i,m; 

      double *ptr = b = malloc(1000*1000*sizeof(double)); 
      printf("Chego(1)\n"); 
       struct msgbuf a; 
      struct envio c; 
      size_t buflen = sizeof(a) - sizeof(long); 
      size_t len2 = sizeof(c) - sizeof(long); 
      printf("Chego(2)\n"); 
      int msid = msgget(key,msgflg); 
      int msid2 = msgget(key2,msgflg); 
      printf("Chego(3)\n");   
      double aux = -1.0; 
      double multiplier = ((1.0/n) * 2); 
      c.mtype = 300; 
      int ny = (int)(1000/n); 

      for(i = 0; i < n; i++) { 
      c.type = (i+1); 
       c.ny = (int)(1000/n); 
       c.yM1 = aux; 
       c.yM2 = aux+multiplier; 
       printf("Chego aqui(2)\n"); 
          if(msgsnd(msid2,&c,len2,0) < 0) { 
        perror("Erro do 1o envio\n"); 
       } 
      } 
     for(m = 0; m < n; m++) { 
       printf("Entrei no ciclo(1)\n"); 

      for(y = 0; y <ny ;y++) { 
       //printf("Chego(4)\n"); 
       for(x = 0; x < 1000;x++) { 
       if(msgrcv(msid,&a,buflen,(long)(m+1),0) < 0) { 
        perror("Erro na recepcao:\n ");  
       } 
       //printf("Chego(5)\n"); 
       b[a.y * ny + a.x] = a.value; 
       } 
      } 

      b = b + (1000/n)*1000; 
      } 
      output_pgm("mandel.pgm", ptr, 1000, 1000, 255); 
      //msgctl(msid, IPC_RMID, NULL); 
      //msgctl(msid2, IPC_RMID, NULL); 
      printf("Processo 1\n"); 
      break; 
      default: 
      for(i = 0;i < n;i++) { 
       switch(fork()) { 
        case -1: 
        printf("Erro de fork"); 
       case 0: 
        exit(0); 
        break; 
       default: 
        printf("Fui lancado\n"); 
        execlp("/home/hyper/Documents/SO2/TP3-4/rec","rec",0); 
        break; 
       } 
       } 
      break;   
     }    
    } 

}; 

的對該程序循環只運行一次

#include <unistd.h> 
#include <stdio.h> 
#include <sys/types.h> 
#include <sys/ipc.h> 
#include <sys/msg.h> 
#include <stdlib.h> 
#include <string.h> 
double type; 
     struct senbuf { 
       long mtype; 
     int x; 
     int y; 
     double value; 
     }; 
int max_iterations = 256; 

double compute_point(double ci, double cr) { 
    int iterations = 0; 
    double zi = 0; 
    double zr = 0; 

    while ((zr*zr + zi*zi < 4) && (iterations < max_iterations)) { 
    double nr, ni; 

    /* Z <-- Z^2 + C */ 

    nr = zr*zr - zi*zi + cr; 
    ni = 2*zr*zi + ci; 

    zi = ni; 
    zr = nr; 

    iterations ++; 
    } 
    return iterations; 
} 

/* The "compute" function computes the Mandelbrot function over every 
    point on a grid that is "nx" points wide by "ny" points tall, where 
    (xmin,ymin) and (xmax,ymax) give two corners of the region the 
    complex plane. 
*/ 

void compute(int msqid,int nx, int ny, double xmin, double xmax, 
     double ymin, double ymax,long type2) { 

    double delta_x, delta_y; 
    int x, y; 
    struct senbuf sen; 
    delta_x = (xmax - xmin)/nx; 
    delta_y = (ymax - ymin)/ny; 
    size_t buflen = sizeof(sen) - sizeof(long); 
    for (y=0; y<ny; y++) { 
    //printf("Ja entrei aqui"); 
    double y_value = ymin + delta_y * y; 
    for (x=0; x<nx; x++) { 
     double x_value = xmin + delta_x * x; 
     sen.mtype = type; 
     sen.x = x; 
     sen.y = y; 
     sen.value = compute_point(x_value,y_value); 
     if(msgsnd(msqid,&sen,buflen,0) < 0) { 
     perror("Erro no envio:"); 
     };  
    // printf("%f",sen.a[y*nx + x]); 
     //buffer[y*nx + x] = compute_point(x_value, y_value); 
    } 
    } 
    printf("Ja mandei %d\n",type2); 
/*sen.mtype=500; 
    sen.test = -1; 
    printf("Ja to a sair\n"); 
    msgsnd(msqid,&sen,buflen,IPC_NOWAIT);*/ 
} 

/* Output the data contained in the buffer to a Portable Greymap format 
    image file. The parameter "max" should be an upper bound for the 
    data values in the buffer. 
*/ 

void output_pgm(char *filename,double *buffer, int nx, int ny, double max) { 
    int i; 
    FILE *file; 
    file = fopen(filename,"w"); 
    fprintf(file,"P2\n"); 
    fprintf(file,"%d %d\n",nx,ny); 
    fprintf(file,"%d\n",(int)max); 
    for (i=0; i<nx*ny; i++) { 
    if (!(i%nx)) fprintf(file,"\n"); 
    fprintf(file,"%d ",(int)buffer[i]); 
    } 
    fclose(file); 
} 

int main() 
{ 
    int msqid; 
    int msqid2; 
      struct recep { 
      long mtype; 
      long type; 
      int ny; 
      double yM1; 
      double yM2; 
     }; 

    struct recep a; 
    size_t len = sizeof(a) - sizeof(long); 
    key_t key = 124; 
    msqid = msgget(key, 0666); 
    if(msgrcv(msqid, &a, len, 300, 0) < 0) { 
      perror("Error checking"); 
    }; 
    printf("Dados :\n Tipo : %d\n Ny: %d\n,yM1 : %f\n yM2: %f\n",a.type,a.ny,a.yM1,a.yM2); 


    type = a.type; 
    printf("Vou iniciar o compute"); 

    key_t key2 = 123; 
     msqid2 = msgget(key2,0666);  
    compute(msqid2,1000,a.ny, -1.0, 1.0,a.yM1,a.yM2,a.type); 
} 

回答

1

在你的第一個switch語句創建一個孩子做什麼它做。父進入第二個switch語句,其中孩子立即退出,父母與「rec」可執行文件重疊。父母不再執行 - 它是程序「rec」。你永遠不會執行多個循環,因爲正在執行的代碼在那時已經消失了。如果你想讓多個「rec」的實例運行,你應該對不是父母的孩子使用execlp

編輯

有兩個系統調用waitwaitpid,提供各種選項。這些簡單的是wait,並且應該足夠用於你正在做的事情。爲您創建的每個子項定義並增加父項中的計數器。然後,而不是退出父母,你等待所有的孩子完成。這樣簡單的事情應該就足夠了:

for (int i = 0; i < counter; i++) 
{ 
    wait(NULL); 
} 
+0

是的我已經把execlp放在孩子上了,我應該把exit(0)放在父級上嗎? – rjcossa

+0

您可以退出父母,但可能會更好地等待孩子。 – Duck

+0

你好,請你告訴我如何等待孩子? – rjcossa