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

Programar em C

Discussão em 'Programação' iniciada por MarcoSamoes, 2 de Dezembro de 2012. (Respostas: 4; Visualizações: 847)

  1. Exercise 8: Desenvolver um programa designado ficha02exer08.c no qual são criados
    inicialmente dois processos filho.
    O primeiro processo irá escrever num ficheiro ficha02exer08-aleatory.dat, números aleatórios
    localizados entre dois valores fornecidos ao programa através da linha de comando. A escrita
    dos números deverá ser separada por 1s.
    O segundo processo calculará recursivamente a média dos números produzidos e escreverá o
    resultado no ficheiro ficha02exer08-recursive.dat. O cálculo deverá ser separado por 1s.
    Também fornecida através da linha de comando será a duração total do programa. Quando este
    tempo terminar o processo pai deverá criar o terceiro e quarto processos com a função indicada
    em baixo e em seguida terminar.
    O comando para correr o programa durante 10 s e considerando os valores entre 20 e 30 será:
    ./ ficha02exer08 10 20 30
    A formula para calcular a média de forma recursiva é dada por:

    seria este o enunciado de programaçao simples em C, mas agora tenho que utilizar threads para fazer o mesmo programa:
    Deste modo, o programa original deve ser
    melhorado de forma a incluir entre outras as seguintes funções:
    - criação de threads;
    - término de threads;
    - joining de threads.


    e tenho um problema, dá-me segmentation fault e nao percebo porque :/
    Aqui vai o código:

    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <pthread.h>
    #include <time.h>
    #include <math.h>


    int linf;
    int lsup;
    int v=0;


    void *thread_save_file(void *arg){
    FILE * pFile;
    float t=0.5;
    srand ( time(NULL) );
    lsup=lsup-linf;
    while(1){
    pFile = fopen ("aleatory.dat","a");
    v = rand() % lsup + linf;
    fprintf(pFile,"%i ", v);
    fclose(pFile);
    sleep(1);
    }
    pthread_exit(NULL);
    }


    void *thread_avg(void *arg){
    FILE *pFile;
    float t=0.5, avg, avg1;
    int n = 1;
    srand ( time(NULL) );
    while(1){
    pFile = fopen ("recursiveaverage.dat","a");
    avg1 = avg1 * (n-1);
    avg = (avg1 * (n-1) + v) / n;
    fprintf(pFile,"%.2f ", avg);
    n++;
    fclose(pFile);

    sleep(1);
    }
    pthread_exit(NULL);
    }


    int main (int argc, char **argv) {
    int tempo,res;


    tempo = atoi (argv[1]);
    linf = atoi (argv[2]);
    lsup = atoi (argv[3]);


    pthread_t th1,th2;
    void *thread_result;
    pthread_create(&th1, NULL, thread_save_file, NULL);
    pthread_create(&th2, NULL, thread_avg, NULL);
    sleep(tempo);
    pthread_cancel(th1);
    pthread_cancel(th2);
    printf("Programa executado com sucesso... confira os dados.\n");
    pthread_join(th1, &thread_result);
    pthread_join(th2, &thread_result);
    }

    se me puderem ajudar agradecia :/
     
  2. besty

    besty Power Member

    Nunca ouviste falar do GDB? É uma óptima ferramenta para detectar segmentation faults. Aconselho a tentares utilizar e tentares descobrir por ti onde essa fuga acontece.
     
  3. (gdb) run
    Starting program: /home/marco/Documentos/Ficha 5/a.out
    [Thread debugging using libthread_db enabled]
    Using host libthread_db library "/lib64/libthread_db.so.1".


    Program received signal SIGSEGV, Segmentation fault.
    0x00007ffff7843f24 in ____strtoll_l_internal () from /lib64/libc.so.6
    Missing separate debuginfos, use: debuginfo-install glibc-2.15-58.fc17.x86_64


    aparece isto, o que devo fazer? nunca utilizei o gdb :/
     
  4. mauro1855

    mauro1855 I'm cool cuz I Fold

    Custa-me bastante a acreditar que estás "nesse nível" (threads, etc) e nunca usaste o gdb.
    Normalmente o GDB costuma indicar exactamente a linha onde se dá o problema, coisa que não estou a ver nesse caso.

    Uma ferramenta alternativa é o valgrind, que corres ./valgrind --leak-check=full ./ficha02exer08 10 20 30

    Não esquecer: sempre que se faz o debug de um programa, este deve ser compilado com a flag -g ou -ggdb. Caso contrário o valgrind não te vai dar a linha onde recebeste o sinal SIGSEGV (Segmentation Fault) - sinceramente nem sei se o gdb funciona sem ser compilado com essa flag.

    [EDIT] Hmmm... Confesso que já estou algo ferrugento com as threads, mas.... porque motivo estás a fazer pthread_cancel() e logo de seguida pthread_join()? Em principio estará aqui o problema: para deixar a thread correr ou fazes join ou fazes detach... não vais fazer um cancel e depois tentar fazer join a uma thread que supostamente mataste... Mas posso estar a confundir.

    Cumps
     
  5. besty

    besty Power Member

    Sim, de facto esqueci-me de referir isso. Tens que compilar com a flag -g, ou seja, gcc -g -c ...

    Tens aqui um cheat sheet para o gdb, é muito fácil.
    http://darkdust.net/files/GDB%20Cheat%20Sheet.pdf
    Se começares a utilizar vai te salvar horas de pancadaria nas paredes.
     

Partilhar esta Página