Попытка выяснить, почему дочерние процессы завершаются раньше, чем они должны - PullRequest
0 голосов
/ 12 июля 2011

Я пытаюсь написать программу, в которой родительский процесс будет обрабатывать n дочерних элементов (номер_узла дочерних элементов) и где дочерние элементы должны выполнять определенную задачу, которая одинакова для каждого дочернего элемента.

После размещения нескольких printf в моем коде я понял, что в цикле for в дочерних процессах есть ошибка, заключающаяся в том, что for не заканчивается в нужном месте, например, если код читает, for(p=0;p<=10; p++) printf показывает, что процесс не имеет значения более p = 6!

Я действительно новичок в этом, и хотя я искал в Интернете, я не нашел ничего полезного! Может ли кто-нибудь помочь мне, пожалуйста?

#include "ranlib.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>


#define node_number 1 
#define seed1 123455L
#define seed2 54321L
#define floor_rates {{0,1,1},{1,0,1}}
// the floor_rates should be intialized at the beginning and they specify the amount
// of flow rate to a specific destination from a specific node, for example
// floor_rates[k][i] is the amount of data node i has for destination k.
#define numofflows 2

float **diagonalcreation(int matsize, float *matrix)//, float **diagonal)
{
int i;
int j;
int k;
float **diagonal;
diagonal=malloc(sizeof(float *)*matsize);
for(i=0;i<matsize;i++)
{
    diagonal[i]=malloc((sizeof(float))*matsize);
}
for(i=0; i<matsize;i++)
{
    for(j=0;j<matsize; j++)
    {
        if(i==j)
        {
            diagonal[i][j]=matrix[i];
        }
        else
        {
            diagonal[i][j]=0;
        }
    }
}

for( k=0;k<matsize; k++)
{
    printf("behnaz hastam\n");
    for(j=0; j<matsize; j++)
    {
        printf("%f\t",diagonal[k][j]);
    }
}
return diagonal;
}


int main()
{
    float c_mean[node_number][node_number];
    pid_t pid[node_number];
    int check;
    check=0;
     //   int index;
     // index=0;
    float c_var[node_number][node_number];
    struct nodes{ 
        float *a;
        float *b;
        float *r;
        int length_r;
        float *s;
        int length_s;
        float **A;
        float **B;
        //right now we have not implemented the DIV protocol but when we do there is a need   for a different variable named seq_number_rec which is the last sequence number recieved.
        //last_seq_number_sent;
        //ack
        float **lambdaprimey_x_x;
        float **lambdax_y_x;
        float lambdax_x_x[numofflows];
        float **t;
        float **ttemp;
        float **tprime;
        float **lambdacomputeprime;
        float lambdacompute[numofflows];
        int *neighbors;
        int length_neighbors;


    } node[node_number];

    int i;
    int j;
    //int numofflows;
    /* srand((unsigned)time(0));
    seed1=random();//12345L;
    seed2=random();//54321L;*/
    setall(seed1,seed2);
    //signal(SIGCHLD, SIG_IGN);
       for(i=0;i<=node_number-1;i++)
    {
        for(j=0; j<=i-1; j++)
        {

            c_mean[i][j]=genchi(1.0);
             if (c_mean[i][j]>1)
             {
             c_mean[i][j]=1.0/c_mean[i][j];
             }
             if(i==j)
             {
             c_mean[i][j]=0;
             }
        }

    }
     for(i=0;i<=node_number-1;i++)
     {
     for(j=i; j<=node_number-1; j++)
     {
     c_mean[i][j]=c_mean[j][i];

     }
     }
    //we are assuming that the links are bimodal with a certain probability to be up or  down.
    for(i=0;i<=node_number-1;i++)
    {
        for(j=0;j<=node_number-1; j++)
        {
            c_var[i][j]=c_mean[i][j]*(1-c_mean[i][j]);
        }
    }
    // pid[0]=fork();

    for(i=0;i<node_number;i++)
    {
        pid[i]=fork();
        if(pid[i]==0)
        {
            int *temp_n=node[i].neighbors;
            float *temp_a=node[i].a;
            float *temp_b=node[i].b;
            float *temp_r=node[i].r;
            float *temp_s=node[i].s;
            //pid[i]=fork();

            int p;
            //The first step is to do the initialization in each process.
            for(p=0; p<=10; p++)
            {
                if(i==0){
                    printf("%d %d %d\n\n\n",p,i, node_number);}
                node[i].length_neighbors=0;

                if(c_mean[i][p]!=0)
                {
                    *temp_n=p;
                    temp_n++;
                    node[i].length_neighbors++;
                    *temp_a=c_var[i][p];
                    temp_a++;
                    *temp_b=c_var[p][p];
                    temp_b++;
                    *temp_r=c_mean[i][p];
                    temp_r++;
                    *temp_s=c_mean[p][i];
                    temp_s++;
                    free(&temp_n);
                    free(&temp_a);
                    free(&temp_b);
                    free(&temp_s);
                    free(&temp_r);
                }

            }


              node[i].A=diagonalcreation(node[i].length_neighbors,node[i].a);//, float    **diagonal)

    /*        for( k=0;k<node[i].neighbors; k++)
            {
                printf("\n");
                for(j=0; j<node[i].neighbors; j++)
                {
                    printf("%f\t",node[i].A[k][j]);
                }
            }
            */
            free(node[i].A);
            printf("behnaaaz");
            exit(0);

        }
        else if(pid[i]<0)
        {
            printf("error_pid");
            break;
        }

    }
    for(i=0;i<node_number;i++)
    {
        if(pid[i]!=0)
        {
            check++;
        }
    }
    if(check==node_number)
    {
        for(i=0;i<node_number;i++)
        {
            wait(NULL);
            printf("waitover");
        }
    }


    return(0);
}

Ответы [ 2 ]

1 голос
/ 12 июля 2011

Во-первых, для проверки ошибок не используйте printf() ... вместо этого используйте fprintf и выводите в stderr, так как это не буферизует, где stdout и printf делают буфер вывод, поэтому использование этих функций с stdout не обязательно будет выводиться на консоль в точке вызова из-за буферизации.

Во-вторых, в цикле for вы освобождаете память для указателей, которые, по ее мнению, не были выделены через malloc(). Это приведет к неопределенному поведению, поскольку вы можете вызывать free() только для того же указателя, который был возвращен при вызове malloc() ... вы не можете высвободить "часть" массива ... вы можете только освободите весь блок выделенной памяти сразу после того, как вы закончите с ним.

В-третьих, вы передаете free() указатель на значение, которое было выделено в стеке (то есть, temp_n и т. Д.). Таким образом, вы фактически передаете указатель на адрес в стеке, который указывает на адрес в куче, на free(), а не на значение указателя на адрес памяти в куче, который был возвращен из malloc(). В любом случае, вы все равно не можете освободить часть массива, что, по-видимому, вы пытаетесь сделать.

0 голосов
/ 05 апреля 2013

Обратите внимание, что при использовании fork () дочерние процессы не обмениваются данными ни с родителями, ни с родительскими процессами!Вы не можете настроить структуру данных в родительском объекте, а затем использовать fork (), чтобы дочерние процессы заполнили данные, и, наконец, прочитать данные в родительском объекте.Каждый дочерний процесс получает свою индивидуальную копию структуры данных, которая исчезает при завершении дочернего процесса.

Чтобы создать дочерние процессы, которые совместно используют данные, вы должны использовать pthread_create ().

...