1. Este site usa cookies. Ao continuar a usar este site está a concordar com o nosso uso de cookies. Saber Mais.

[Help] C com comando Fork()

Discussão em 'Programação' iniciada por Neo4, 18 de Abril de 2008. (Respostas: 11; Visualizações: 2918)

  1. Neo4

    Neo4 Banido

    Boas estive aqui a fazer um exercicio para a minha cadeira de sistemas operativos e estou aqui com um problema:
    Basicamente preenchi uma matriz[10][100] com valores apartir de zero e agora quero procurar se um dado numero existe quantas vezes na matriz usando um acumulador para contar.
    mas isto não está a dar, se tirarmos o \n do primeiro printf ele até vai imprimir esse texto 2x (agora porque antes de fazer algumas alterações repetia 10x!)
    não percebo também como é que o acumulador quando encontra o valor fica a 4 e não a 1!
    vejam se me conseguem ajudar ssf!

    código:
    Código:
    #include <sys/types.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
        main (int argc, char **argv){
       	int matriz[10][100];
       	int i, j, valor=0, t, p;
    	int ad=300, r, ac=0;
    
    	printf("valor inicial do ac=%d\n",ac);
    
       	  
       	  for(t=0; t<10; t++){
       	  	for(j=0; j<100; j++){
       	  		matriz[t][j]=valor; valor++;
       	  	}
       	  }
    
    
    
    	 for(i=0; i<10; i++){
    		p =fork();
    
    		if(p == -1) {
                            perror("fork");
                            exit(EXIT_FAILURE);
                    }
    
    		if(!p){		
    			 search(matriz[i], ad, ac);
    			exit(0);
    		}
    	 }
    
    
    	printf("nr de vezes:%d\n\n", ac);
    
    }
    
    
    	search(int matriz[], int ad, int *acum){
    		int c,a;		
    		for(c=0; c<100; c++){
    			if(matriz[c]==ad) {acum++;printf("apanheite!%d\n",acum);}
    		}
    		return(*acum);
    
    	}
    Obrigado
     
  2. Baderous

    Baderous Banido

    search(matriz, ad, &ac);

    Não estou no Ubuntu para testar agora, mas muda isto e vê se dá.
     
  3. Neo4

    Neo4 Banido

    eu ja achava que nao mas fui confirmar, isso ainda faz pior...
    assim estas a passar o valor do endereço e tu queres passar é mesmo o valor.

    o problema acho que nao está aí mas sim no facto de para o ac ficar a 4(o valor 300 é encontrado na 4º iteraçao) e também nao ficar gravada no acum o valor correcto..
     
  4. sapropel

    sapropel Power Member

    ta tudo mal, aconselho-te a ler sobre ponteiros 1º.
    ai vai umas dicas.

    Código:
    (...)
    if(!p){		
        search(matriz[i], ad, ac); //a funcao recebe um endereço por isso é &ac
        exit(0);
    }
    
    (...)
    search(int matriz[], int ad, int *acum){ //falta o tipo de retorno (int neste caso)
    	int c,a;		
    	for(c=0; c<100; c++){
    		if(matriz[c]==ad){
                        acum++; //acum++? queres que ele avance no endereço ou no valor? é *acum++
                        printf("apanheite!%d\n",acum);
                    }
    	}
    	return(*acum);
    }
    
    nem sequer vi se o algoritmo em si está bem, so o codigo.
     
    Última edição: 18 de Abril de 2008
  5. Neo4

    Neo4 Banido

    corre com as tuas alteraçoes e com as minhas e ve a diferença! eu quero somar ao valor e não ao endereço
    da tua maneira no fim ele vai imprimir o valor do endereço e nao o que está la dentro..
    com: search(matriz, ad, &ac);
    o resultado vai ser o endereço...
    o *acum no ++ nao alterou em nada e penso que assim estas a somar é ao endereço e nao ao acum, mas nao tenho a certeza disto!

    de qualquer das maneira continua o problema...

    tirei os apontadores e no printf "apanheite" ja imprime só o 1 mas no fim o resultado continua a dizer que o ac está a zero...
    por isso é que tentei com apontadores para ver s na memoria sp ficava melhor guardado =)
     
    Última edição: 18 de Abril de 2008
  6. sapropel

    sapropel Power Member

    epah.. eu não corrigi o teu codigo (o que eu postei tava igual ao original), so meti comments a frente com dicas. isso ta a fazer output do endereço pk acum é um ponteiro e tás a passa-lo directamente no printf()

    Código:
    #include <sys/types.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int    main (int argc, char **argv){
       	int matriz[10][100];
       	int i, j, valor=0, t, p;
    	int ad=300, r, ac=0;
    
    	printf("valor inicial do ac=%d\n",ac);
    
       	  
       	  for(t=0; t<10; t++){
       	  	for(j=0; j<100; j++){
       	  		matriz[t][j]=valor; valor++;
       	  	}
       	  }
    
    
    
    	 for(i=0; i<10; i++){
    		p =fork();
    
    		if(p == -1) {
                            perror("fork");
                            exit(EXIT_FAILURE);
                    }
    
    		if(!p){		
    			 search(matriz[i], ad, &ac);
    			exit(0);
    		}
    	 }
    
    
    	printf("nr de vezes:%d\n\n", ac);
    
    }
    
    
    int	search(int matriz[], int ad, int *acum){
    		int c,a;		
    		for(c=0; c<100; c++){
    			if(matriz[c]==ad) {*acum++;printf("apanheite!%d\n",*acum);}
    		}
    		return(*acum);
    
    	}
    
     
    Última edição: 18 de Abril de 2008
  7. Neo4

    Neo4 Banido

    pa o problema persiste porcausa do fork... e mesmo com essa tua soluçao o resultado é igual a como eu tinha (quer dizer agora aparece 3 no printf do apanheite e antes aparecia 4 :)

    tirando os apontadores todos essa parte fica resolvida ta visto que com eles nem eu nem tu vamos lá à 1º =)

    se percebers alguma coisa do fork() ve s consgues perceber pkek ta mal...

    obrigado

    EDIT: ainda em relaçao aos apontadores fui tirar teimas poe o codigo assim:
    int search(int matriz[], int ad, int *acum){
    printf("com *:%d sem:%d", *acum++, acum);
    return(*acum);
    }
    e vais ver com o *acum++ nao vai fazer nada, imprime zeros no *acum e os endereços no acum, poe depois o ++ no acum e vais ver o *acum a aumentar (o valor apontado, nao o endereço) e o acum a manter-se intacto!
     
    Última edição: 18 de Abril de 2008
  8. qual o enunciado ao certo???

    so sabendo o objectivo é que posso ajudar mais concretamente
    se o objectivo for algo do género,
    criar N processos para procurar no array dividindo-o em N partes
    e no final imprimir o numero de vezes que encontrou X no array todo
    vais precisar mais do que forks...

    mais pormenores so depois de saber o que é suposto fazer...
     
  9. Neo4

    Neo4 Banido

    o enunciado é mesmo esse!

    pois eu ate mandei mail ao prof e ele diss que ja me estava a adiantar ao que foi dado...
    so tinha que por a imprimir sempre que o nr fosse encontrado o que era de caras.

    anyway consegui na mesma uma soluçao:
    no processo pai pus um wait(&nr); e depois um WEXITSTATUS que lia esse valor (isto claro porque só tinha um processo filho a correr de cada vez!) e ia assim somando a um inteiro no processo pai e voilá :)

    o stor disse que para funcionar como eu tava a tentar é preciso criar um espaço de memória partilhado entre pai e filhos, assunto da próxima aula :)

    abraços
     
  10. pois!

    quando fazes um fork(), estas a replicar toda a memoria associada ao teu programa,
    ou seja se alteras uma variável em algum dos filhos o pai não tem conhecimento dessa alteração,
    porque cada um tem a sua própria copia das variáveis.

    para a primeira parte, ou seja, para imprimir sempre que encontras basta por uns printf na search ao encontrar o valor procurado, convem no pai fazer wait pelos filhos para eles não ficarem zombies

    pode ser algo do género
    for(i=0;i<N;i++) wait(NULL); // N é o numero de filhos que fizeste

    ---//---
    para em cada filho contares as ocorrências de um dado valor
    e depois passares a contagem do filho para o pai a forma mais fácil é
    passares a contagem com a função exit(CONTAGEM)
    algo do género
    Código:
    (...)
    if(!p){        
      ac = search(matriz[i], ad);
    /* a função search retorna o numero de ocorrências de ad em matriz[i] */
      exit(ac);
    }
    (...)
    no fim de lançares os filhos, esperas que eles terminem e ves o seu valor de saida

    Código:
    int status;
    int ocorrencias = 0;
    (...)
    for(i=0;i<N;i++){
      wait(&status);
      if(WIFEXITED(status)){ /* verifica se o programa saiu normalmente (usando o exit) */
        ocorrencias += WEXITSTATUS(status); /* incrementa o valor passado pelo filho ao acumulador */
      }
    }
    a limitação de usar o exit para passar valores é que so podes passar 8 bits ou seja valores entre 0 e 256
     
    Última edição: 19 de Abril de 2008
  11. raVemjr

    raVemjr I'm cool cuz I Fold

    Gee, depois de ver isto cheguei a conclusão que o melhor mesmo é estudar SO durante as férias senão para o ano afundo de novo...
     
  12. Neo4

    Neo4 Banido

    Foi exactamente isso que eu fiz :)
     

Partilhar esta Página