C komunikacja dzieci z rodzicem pipe

0

Napisałem program który tworzy określoną liczbę dzieci - mam nadzieje że jest poprawny. Chciałbym teraz zapewnić komunikacje między każdym procesem dziecka, a rodzicem za pomocą potoków pipe. (dziecko wysyła wiadomość do rodzica). Napisałem kawałek kodu do tego, ale nie chce działać poprawie.

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

int main(int argc, char **argv)
{
        pid_t pid;


        if(argc < 3)
        {
                printf("Not enought arguments");
                exit(0);
        }

        int number = atoi(argv[2]); // number of childern
        pid_t pids[number],pid_s;
        int i,n=number,status;
        int pipes[number*2];
        char buff[512];
        int flaga=0;
        int r=0,w=0,rr=0,ww=0,fd;

        for(i=0; i<n; i++) //inicjacja pipe
        {
                if(pipe(pipes+(i*2)) < 0)
                {
                        perror("failed to allocate pipes");
                }
        }

        if(strcmp("-p", argv[1]) == 0)
        {
                //
                flaga=0; // uzywamy potokow
        }

        if(strcmp("-f", argv[1]) == 0)
        {
                //
                flaga=1; // uzywamy fifo
                char * myfifo = "/tmp/myfifo";

                mkfifo(myfifo,0666);



        }


        switch (pid = fork()) { //tworzenie potomka
           case -1:
                        perror("Error in fork");
                        exit(0);

                        break;
           case 0:

                   for(i=0; i < n; i++) //towrzenie reszty potomkow
                   {
                           if((pids[i] = fork()) < 0)
                           {
                                   perror("error fork");
                           }
                           else if(pids[i] == 0)
                           {
                                //losuje czas
                                int zarodek,czas;
                                zarodek = time(NULL);
                                srand(zarodek);

                                czas = rand()%100; //losuje liczbe z przedzialu <0,99>
                                int val = getpid();
                                if(flaga == 0)
                                {
                                          //wysylanie do rodzica wiadomosci
                                        close(pipes[0+r]);
                                        write(pipes[1+w], &val, sizeof(val)); //wysanie pidu
                                        write(pipes[1+w], &czas, sizeof(czas)); //wyslanie czasu
                                        r+=2;
                                        w+=2;
                                        //spanie
                                        sleep(czas);

                                        printf("Stworzylem dziecko z numerem: %d \n", getpid());
                                }
                                else if(flaga == 1)
                                {
                                        //stworzenie fifo
                                        fd = open(myfifo, O_WRONLY);
                                        //pisanie do fifo
                                        write(fd,&val,sizeof(val)); //wysalnie pidu
                                        write(fd,&czas, sizeof(czas)); //wyslanie czas
                                        close(fd);
                                        sleep(czas);

                                }
                                        execvp(argv[0],NULL);
                           }
                   }

                   while(n > 0)
                   {
                           pid_s = wait(&status);
                           --n;
                   }
                          break;
            default:

                   if(flaga==0)
                   {

                          //odbieranie wiadomosci od potomkow
                        for(i=0; i<n; i++)
                        {
                                close(pipes[1+rr]);
                                int n;
                                read(pipes[0+ww],&n,sizeof(n));
                                printf("Wiadomosc: %d \n", n);
                                rr+=2;
                                ww+=2;
                        }
                   }
                   else if(flaga == 1)
                   {
                           char bufor[512];
                           fd = open(myfifo, O_RDONLY);
                        for(i=0; i<n; i++)
                        {
                                read(fd,bufor,512);
                                printf("Otrzymalem %s\n", bufor);
                        }
                        close(fd); //zamkniecie
                        unlink(myfifo); //usuniecie

                   }
                   if(wait(0) == -1)
                   {

                   }

                          break;
         }

        return 0;
}
0

Co dokładnie nie działa? Co zwraca execvp?

EDIT: no a gdzie właściwie wołasz f-kcję pipe?

EDIT2: i zainkluduj string.h ;)

0

Procesy potomne się tworzą ok. Teraz chce żeby każdy proces potomny wysłał wiadomość do rodzica i to nie działa, nie wiem jak to zrobić.

0

To jeszcze raz: man pipe Twoim przyjacielem. Gdzie wywołujesz f-kcję pipe żeby faktycznie otworzć potoki[podpowiedź: w Twoim kodzie tego brak ;)]?

0

Zrobiłem update kodu. Chce aby każdy proces potomny wysłał wiadomość ze swoim PID do rodzica. Wysyła, rodzic odbiera, ale zawsze odbiera ten sam numer PID.

0

Jakieś pomysły?

0

To może od początku: jaka ma być hierarchia tych procesów? Bo sprawiasz wrażenie, jakbyś nie do końca wiedział co robisz/chcesz osiągnąć.

Na szybko: popraw strlen na sizeof(val) przy write, to raz; dwa: wywal execvp, po co on tam ma być w ogóle?

0

Poprawiłem kod. Założenie jest takie:

Program tworzy potomka, a ten potomek tworzy N procesów. Procesy mają być uruchamiane jako odesparowany program, dlatego użyłem exec. Każdy utworzony proces ma wysyłać numer PID do procesu rodzica, a rodzic ma to odbierać. Póki co wysyła, rodzić odbiera, ale zawsze ten sam numer PID. Wszystko jasne?

0

Jakieś pomysły?

0

Raz: to się nie skompiluje nawet bo masz myfifo w złym miejscu tworzone. Dwa: nazwa n w odbiorze jest błędogenna, bo tak się już nazywa zmienna określająca górę pętli. Trzy: w pętli 'case 0' teraz wołasz forka z forka, musisz dodatkowo sprawdzać pid pierwszego childa. Exec nadal źle, parametry przekazujesz nieprawidłowo. Zresztą pytanie, czy chcesz przekazać odp. info przez pipe z poziomu programu wołanego przez exec, czy tylko w forku. To pierwsze też się da zrobić, tylko należy przekazać deskryptory plików do nowego procesu.

Jest tam więcej baboli, ale na dziś tyle. ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1