[c] Ajuda com processos

A questão é a seguinte, eu tenho um código em C, para compilar em gcc em que os filhos tem que transmitir ao pai o seu índice e adicionalmente o pai só pode ter um filho de cada ves.


Código:
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>

int main (void)
{
    pid_t pid;
    int i;
    int x;
    
    for (i=1; i<3; i++)
    {
        pid=fork();
        if (pid>0)
        {
            //codigo do pai
            printf("Eu sou o pai e o meu pid é %d\n",pid);
            [COLOR=Magenta]wait(&x);[/COLOR]
            printf("valor de saida do meu filho =%d", x);
        }
        else
        {
            //codigo do filho
            printf("Eu sou o %dº filho\n",i);
            if (i==1)
                sleep(5);
            [COLOR=Magenta]exit(int i);[/COLOR]
        }
        
    }
    return 0;

}
Basicamente o meu problema está na comunicação entre o exit e o wait...


Sei que me falta verificar se o pid for -1 (erro), mas isso verifico amanha quando me levantar...
 
Alguns pontos a considerar:

1. O teu primeiro printf está errado. A rotina fork() não devolve, ao processo pai, o seu próprio PID, mas sim o PID do filho que acabou de ser criado. Correcto seria mostrar algo do género "eu sou o pai e acabei de criar um filho com PID %d".
2. exit(int i); ? O que é isto? O exit recebe um valor inteiro, não uma declaração de uma variável. exit(0); deve chegar com certeza.
3. if (i == 1) sleep(5); qual a razão de teres colocado o primeiro processo filho a dormir 5 segundos?
4. Não é bem um erro, mas acho estranho teres um for com i = 1... i < 3. Tens noção de que isso só te vai dar origem a 2 processos filhos e não a 3?

Cumprimentos.

EDIT: Em relação ao ponto 2, se quiseres mesmo transmitir o índice, deves fazer exit(i); de facto. Mas nunca exit(int i);
 
Última edição:
Alguns pontos a considerar:

1. O teu primeiro printf está errado. A rotina fork() não devolve, ao processo pai, o seu próprio PID, mas sim o PID do filho que acabou de ser criado. Correcto seria mostrar algo do género "eu sou o pai e acabei de criar um filho com PID %d".

tens razão
2. exit(int i); ? O que é isto? O exit recebe um valor inteiro, não uma declaração de uma variável. exit(0); deve chegar com certeza.
O mais importante do exercício é os 2 programas conseguirem comunicar

3. if (i == 1) sleep(5); qual a razão de teres colocado o primeiro processo filho a dormir 5 segundos?
o exercício assim o pede


4. Não é bem um erro, mas acho estranho teres um for com i = 1... i < 3. Tens noção de que isso só te vai dar origem a 2 processos filhos e não a 3?

O exercício só pede para o pai criar 2 filhos



EDIT: Em relação ao ponto 2, se quiseres mesmo transmitir o índice, deves fazer exit(i); de facto. Mas nunca exit(int i);

exit (i) também não funciona, coloquei assim ao inicio, depois fui ver as folhas e coloquei int i para ver se não era um problema de falta de cast.
 
modifiquei o código

Código:
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>

int main (void)
{
    pid_t pid;
    int i;
    int x;
    
    for (i=1; i<3; i++)
    {
        pid=fork();
        if (pid>0)
        {
            //codigo do pai
            printf("Eu sou o pai e o meu pid é %d\n",[COLOR=Lime]getpid()[/COLOR]);
            [COLOR=Magenta]wait(&x);[/COLOR]
            printf("valor de saida do meu filho é %d\n", x);
        }
        else
        {
            //codigo do filho
            printf("Eu sou o %dº filho\n",i);
            if (i==1)
                sleep(5);
            [COLOR=Magenta]exit(i);[/COLOR]
        }
        
    }
    return 0;

}


no entanto o problema da transferência de dados utilizando o exit mantem-se, deviam ser retornados os valores 1 e 2 e não 256 e 512:

qpnnkl.jpg
 
Última edição pelo moderador:
OK, estive a rever o manual da função wait() (http://linux.die.net/man/2/wait), e de facto o valor da tua variável "x" não é suposto ter lá o código de retorno do programa. Existe uma macro para isso na mesma página que é:
WEXITSTATUS(status)

Se não estou em erro, essa macro receberá o teu inteiro "x" e devolverá outro inteiro, que conterá o código de retorno que pretendes. Hás-de experimentar fazer algo do género:

Código:
int codigo_de_retorno = WEXITSTATUS(x)
Depois diz-me se funcionou.
Cumprimentos.

EDIT: Não sei se ficou muito claro, mas caso não tenha ficado, a chamada à macro tem de ser feita depois da chamada ao wait().
 
Última edição:
muito obrigado Miguel, consegui por o exercicio a funcionar.

Código:
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>

int main (void)
{
    pid_t pid;
    int i;
    int x;
    
    for (i=1; i<3; i++)
    {
        pid=fork();
        if (pid>0)
        {
            //codigo do pai
            printf("Eu sou o pai e o meu pid é %d\n",getpid());
            [COLOR=Magenta]wait(&x);[/COLOR]
            if ([COLOR=Magenta]WIFEXITED(x)[/COLOR])
                printf("valor de saida do meu filho é %d\n", [COLOR=Magenta]WEXITSTATUS(x)[/COLOR]);
            else
                printf("o filho não retomou normalmente\n");
        }
        else
        {
            if (pid==-1)
                {
                    printf("Erro ao procriar\n");
                    exit(-1);
                }
                else
                {
                    //codigo do filho
                    printf("Eu sou o %dº filho\n",i);
                    if (i==1)
                        sleep(20);
                    exit(i);
                }
        }
        
    }
    return 0;

}
 
Back
Topo