Блокировка очереди сообщений Мандельброта - 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;         
        }             
    }   

};

Цикл for в этой программе запускается только один раз

#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, в котором дочерний объект немедленно завершается, а родительский объект накладывается на исполняемый файл rec. Родитель больше не выполняется в точке - это программа "rec". Вы никогда не собираетесь выполнять более одного прохода цикла, потому что код, который выполняется, ушел в этот момент. Если вы хотите запустить несколько экземпляров "rec", вы должны использовать execlp на детей не родитель.

РЕДАКТИРОВАТЬ

Есть два системных вызова wait а также waitpid это предоставляет различные варианты. Более простой из них wait и должно быть достаточно для того, что вы делаете. Определите и увеличьте счетчик в родительском элементе для каждого создаваемого вами дочернего элемента. Тогда вместо того, чтобы просто выйти из родителя, вы ждете, пока все дети закончат. Что-то простое, как это должно быть достаточно:

for (int i = 0; i < counter; i++)
{
    wait(NULL);
}  
Другие вопросы по тегам