Adminstrar processos no linux com fork() e pipe bidimensional

1. Adminstrar processos no linux com fork() e pipe bidimensional

Gustavo Azevedo de Matos
#Gustavo

(usa Ubuntu)

Enviado em 27/05/2016 - 17:50h

Olá pessoal, estou fazendo um trabalho no qual eu preciso fazer um gerenciador de processos em c. Nele preciso criar processos e imprimir cada PID na tela, mas estou com dificuldade para administrar os processos. Quando eu escolho a opção de imprimir os processos não acontece nada e não consegui descobrir o que é. Segue o que consegui fazer:

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

int **pipefd;

void filho(int *pipe)
{
pid_t buf;
close(pipe[1]);
while(read(pipe[0],&buf,256) > 0)
printf("%d",buf);
}

int main(){
pid_t *processos;
int num, opc,i,b;

do{
printf("Digite 1 para criar novos processos:\n");
printf("Digite 2 para imprimir os processos existentes:\n");
printf("Digite 9 para sair:\n");
scanf("%d",&opc);

switch(opc){

case 1:
printf("Digite o número de processos a serem criados:\n");
scanf("%d",&num);
pipefd = (int**)malloc(sizeof(int*)*num);
processos = malloc(num*sizeof(int));
for(i = 0;i<num;i++){
pipefd[i] = (int*) malloc(sizeof(int)*2);
pipe(pipefd[i]);
processos[i] = fork();
if(processos[i] == 0){
filho(pipefd[i]);
}

}
break;

case 2:
for(i = 0;i<num;i++){
close(pipefd[i][0]);
b = processos[i];
write(pipefd[i][1],&b,sizeof(int));
if(processos[i] == 0)
filho(pipefd[i]);

}
break;
}

}while(opc!=9);


return 0;

}



  


2. Re: Adminstrar processos no linux com fork() e pipe bidimensional

Paulo
paulo1205

(usa Ubuntu)

Enviado em 28/05/2016 - 00:58h

Você manda sizeof(int) bytes (possivelmente 4 ou 8 bytes) mas, na hora de ler, tenta ler 256. Os processos leitores provavelmente estão parados, esperando mais bytes. Mas mesmo que a leitura termine, você tem um potencial problema logo em seguida, na hora de imprimir o dado recebido: como a saída padrão é orientada a linha, ou você coloca um "\n" na string de formatação do printf() que imprime o dado recebido, ou chama fflush(stdout); caso contrário todas as mensagens impresss pelos processos filhos vão ficar esperando a presença de uma marca de fim de linha, antes de serem efetivamente jogadas para a saída.

Como pipes são unidirecionais, eu recomendo fechar as pontas que não correspondem ao sentido desejado da comunicação logo após o fork(). Além disso, você poderia agrupar informações correlatas sobre cada processo dentro de uma estrutura.

struct proc_data {
pid_t pid;
int send_fd;
};

/* ... */

{
struct proc_data *procs;
int pipe_fds[2];

/* ... */

procs=malloc(n_procs*sizeof *procs);
for(int n=0; n<n_procs; n++){
if(pipe(pipe_fds)==-1){
fprintf(stderr, "Falha ao criar pipe para o %dº processo filho.\n", n+1);
exit(1);
}
procs[n].pid=fork();
if(procs[n].pid==-1){
fprintf(stderr, "Falha ao criar o %dº processo filho.\n", n+1);
exit(1);
else if(procs[n].pid==0){
/* Fecha descritores já abertos herdados do processo pai. */
for(int m=0; m<n; m++)
close(procs[m].send_fd);
/* Fecha a ponta de escrita do pipe deste processo. */
close(pipe_fds[1]);
filho(pipe_fds[0]);
exit(0); // Termina processo filho.
}
procs[n].send_fd=pipe_fds[1];
close(pipe_fds[0]);
}
}







Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts