Visualizzazione dei risultati da 1 a 5 su 5
  1. #1
    Utente di HTML.it
    Registrato dal
    Jan 2013
    Messaggi
    3

    [C] - Problema con Pthreads

    Ciao a tutti,

    Sono nuovo del forum e sto cercando di imparare a programmare da autodidatta visto che lavoro di già.

    Mi sono imbattuto ieri in questo esercizio:
    Scrivere un programma che attiva una serie di thread per effettuare il calcolo approssimato di PiGreco.

    Il programma principale prende come input da riga di comando un parametro che indica il grado di accuratezza (accuracy) per il calcolo di π e il tempo massimo di attesa dopo cui il main interrompe tutti i thread.

    I thread vengono utilizzati (cercando di massimizzare il numero di operazioni effettuate nel lasso di tempo a disposizione) per effettuare le seguenti operazioni per il calcolo di π tramite la serie di Gregory-Leibniz: π = 4/1 − 4/3 + 4/5 − 4/7 + 4/9 − 4/11 ...

    I thread vengono tutti interrotti quando una delle due condizioni seguenti risulta verificata:
 1) il tempo massimo di attesa è stato superato;

    2) la differenza tra il valore stimato di π e il valore Math.PI è minore di accuracy.


    E' un esercizio che devo svolgere in C con l'ausilio dei Pthread.
    La soluzione a cui avevo pensato è la seguente:
    codice:
    #include <stdio.h>
    #include <pthread.h>
    #include <time.h>
    #include <math.h>
    #include <unistd.h>
    
    int check = 0;
    int MAX_THREADS = 4;
    
    void *thread_function(void *arg)
    {
        float pi_greco = 0;
        float pi_grecotot = 0;
        float error;
        int i = 0;
        int denominatore = 1;
        float accuracy;
        accuracy =*(float*)arg;
        do {
            if (i%2 == 0) {
                pi_greco = (float)4 / (float) denominatore;
                denominatore = denominatore + 2;
            }
            else{
                pi_greco = -(float)4 / (float)denominatore;
                denominatore = denominatore + 2;
            }
            pi_grecotot = pi_grecotot + pi_greco;
            i++;
            error = pi_grecotot - M_PI;
        } while (fabs(error) > accuracy && check == 0);
        printf("Il valore di pigreco approssimato a %f è %f\n", accuracy, pi_grecotot);
        return NULL;
        
    }
    
    void *thread_check_time(void *arg)
    {
        int t_max;
        t_max = *(int*)arg;
        if (t_max == 0)
        {
            printf("Impossibile procedere tempo inserito uguale a 0");
        }
        sleep(t_max);
        check = 1;
        return NULL;
    }
    
    
    int main()
    {
        int t_max;
        float accuracy;
        printf("inserisci il tempo massimo di attesa(espresso in secondi): ");
        scanf("%d", &t_max);
        printf("inserisci il grado di accuratezza");
        scanf("%f", &accuracy);
        pthread_t thread_time;
        pthread_t thread_leibniz;
        pthread_create(&thread_time, NULL, thread_check_time, &t_max);
        pthread_create(&thread_leibniz, NULL, thread_function, &accuracy);
    }
    Ho riscontrato però questi problemi:
    1) Non riesco a far rispettare le due condizioni di uscita ovvero o timeout oppure l'errore è maggiore di accuracy
    2) Rileggendo il testo sembrerebbe che io debba lanciare N threads (al fine forse di sfruttare tutti i core del processore) ma non riesco a suddividere ulteriormente il programma in più rispetto a come ho fatto io......

    c'è qualcuno che può darmi una mano??

    Grazie

  2. #2
    Utente di HTML.it
    Registrato dal
    Jan 2013
    Messaggi
    3
    Non c'è un'anima pia che mi può spiegare dove sbaglio e come sistemare il codice???!!

    Praticamente io dovrei sfruttare tutti i core della macchina e quindi dovrei usare 3 thread per i calcoli sempre nella stessa funzione thread_leibniz

    mi dite come posso fare???

  3. #3
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Prima di uscire dal main() metti dei pthread_join() per essere sicuro che i thread finiscano, altrimenti finito il main(), finito tutto.
    Poi non vedo il senso di mettere una sleep() in un thread per aspettare un altro thread, dato che solo il thread che la contiene viene sospeso: quella sleep() va lasciata nel main().
    Infine se lanci più di un thread per il calcolo devi mettere un mutex per proteggere la variabile accuracy interna alla funzione thread che in realtà è globale visto che la passi da fuori.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  4. #4
    Utente di HTML.it
    Registrato dal
    Jan 2013
    Messaggi
    3
    La sleep l'avevo inserita al fine di rispettare una della condizioni della traccia.

    In maniera pratica perchè io altrimenti ti giuro non capisco come sistemeresti il codice?

  5. #5
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Originariamente inviato da 88Leo88
    In maniera pratica perchè io altrimenti ti giuro non capisco come sistemeresti il codice?
    Non m'intendo molto di pthread quindi prendili come suggerimenti di massima (nel senso che poi dovrai mettere le giuste funzioni)
    codice:
    /* variabile globale di tipo mutex fornita dai pthreads */
    var global_mutex;
    /* variabile di controllo globale da proteggere con un mutex */
    int exit_from_thread; 
    int main()
    {
        int t_max;
        float accuracy;
        printf("inserisci il tempo massimo di attesa(espresso in secondi): ");
        scanf("%d", &t_max);
        printf("inserisci il grado di accuratezza");
        scanf("%f", &accuracy);
        pthread_t thread_leibniz;
        exit_from_thread = 0;
    
        /* pseudo codice */   
        init_mutex( global_mutex );   
    
        pthread_create(&thread_leibniz, NULL, thread_function, &accuracy);
        sleep(t_max); /* sospende il main per tot tempo */
    
        /* pseudo codice per la critical region */   
        mutex_lock( global_mutex )
        exit_from_thread=1;
        mutex_unlock ( global_mutex );
    
        pthread_join(thread_leibniz);
    
    }
    
    void *thread_function(void *arg)
    {
        ...
        /* variabile temporanea */
        int request_for_exit = 0;
        do {
            ...
            /* mai uscire dalla funzione senza aver rilasciato il mutex o si blocca tutto */
            mutex_lock( global_mutex )
            if (exit_from_thread==1) {
                request_for_exit = 1;
            }
            mutex_unlock ( global_mutex );
        
        } while (fabs(error) > accuracy && check == 0 && request_for_exit !=0 );
        printf("Il valore di pigreco approssimato a %f è %f\n", accuracy, pi_grecotot);
        return NULL;
        
    }
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.