Pthread_create passaggio di un valore intero

di il
14 risposte

Pthread_create passaggio di un valore intero

Ciao a tutti!
ho riscontrato più volte questo warning.
warning: cast from pointer to integer of different size
Questo perchè quando vado a chiamare pthread, il più delle volte, la uso così:
 pthread_create(&tid, NULL, &func, (void *) valoreintero); 
Questo perchè ho bisogno di passare un valore intero alla funzione func. Ad esempio passare se ho un array di threads passare l'indice dell'array di quale thread sto generando.

Ovviamente non posso fare un cast da intero a puntatore a vuoto, ecco perchè il warning.
Ma non posso manco passare un puntatore ad intero... altrimenti creerei race condition!
E sinceramente voglio evitare di utilizzare i mutex.

Quindi esiste un'altra soluzione?
Ovvero, la mia domanda è questa: c'è un modo per passare alla func un intero senza dover ricorrere ai mutex e al tempo stesso non generando più il warning?

Approfitto anche per un altra domanda sempre sul pthread_create.
Come faccio a passare alla funzione func due interi?
Sono costretto a fare una struct, oppure gli li posso passare in un'altro modo?

Grazie

14 Risposte

  • Re: Pthread_create passaggio di un valore intero

    Ti perdi un un bicchier d'acqua...
    
    pthread_create(&tid, NULL, &func, &args);
    
    args è il tuo intero o la tua struttura per passare quanti parametri vuoi.
    ovviamente il cast viene fatto nella func
  • Re: Pthread_create passaggio di un valore intero

    Scusami non ho capito. Probabilmente hai ragione che mi perdo in un bicchier d'acqua.

    Allora nella pthread_create devo passare un intero o un puntatore ad intero?

    Di solito faccio così:
    
     pthread_create(&tid, NULL, &func, (void *) valoreintero);
    ....
    void *func(void *arg){
     int val = (int) arg;
    }
    
    ma mi da il warning di prima.

    Facendo, invece, così:
    
     pthread_create(&tid, NULL, &func, (void *) &valoreintero);
    ....
    void *func(void *arg){
     int val = *(int *) arg;
    }
    
    creo condition code!

    Quindi cosa devo fare? mi scrivi il codice?
  • Re: Pthread_create passaggio di un valore intero

    Un ptr ad int oppure un ptr a quello che ti pare senza fare il cast in chiamata.
    Sono sul cell e ci metto un casino a scrivere codice ma ti allego un link dove puoi
    trovare un esempio valido di ció che cerco di spiegarti.
    http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_create.3.html
  • Re: Pthread_create passaggio di un valore intero

    Grazie mi rispondi addirittura dal cellulare!
    Ma scusa, quindi passo alla funzione func un puntatore a intero. Quindi più thread accedono alla stessa variabile, ovvero l'intero. E quindi si crea condition code!
    Nell'esempio, che mi hai passato, però non faceva uso di mutex. Non capisco!
  • Re: Pthread_create passaggio di un valore intero

    Nell'esempio non si crea condition code ! e nemmeno si fa uso di mutex....
    Guarda meglio l'esempio l'allocazione delle struct per un multithread....
    non mi sembra cosi trascendentale
  • Re: Pthread_create passaggio di un valore intero

    ... ma il valore(ii) che vuoi passare sono ad esclusivo uso del singolo thread o sono in comune?
    se fossero in comune allora mutex è obbligatorio
  • Re: Pthread_create passaggio di un valore intero

    Mi sa che non riesco a spiegarmi.
    Supponiamo questo:
    
    int main(){
      pthread_t tid[MAXTHREADS];
      for(i = 0; i < MAXTHREADS; i++)
         pthread_create(&tid[i], NULL, &func, &i);  
    }
    void *func(void *arg){
      int id;
      id = *(int *)arg;
      ....
    }
    
    Questo è quello che mi hai detto di fare, giusto?
    Ma in questo modo se creo 10 threads. Tutte e 10 accederanno alla variabile i perchè io gli ho passato ad ognuno il puntatore a tale variabile.
    Quindi, perchè non potrebbe accadere questo?
    viene creato il primo thread --> i = 0;
    viene creato il secondo thread --> i = 1;
    primo thread --> assegna a id = i --> id = 1;
    secondo thread --> assegna a id = i --> id = 1;
    ERRORE!!!
  • Re: Pthread_create passaggio di un valore intero

    Ripeto:
    i è in comune o esclusiva?
  • Re: Pthread_create passaggio di un valore intero

    Ahahah... l'unico uso di i, è quello che vedi.
    la passo alla funzione e la passo a id (tramite arg si intende) poi uso id e non i.
    Quindi credo che sia esclusiva...
    ma è proprio qui il punto, secondo me può benissimo accadere quello che ti ho scritto sopra.
    Il main genera i primi 2 threads quindi i viene cambiata.
    Ad entrambi thread viene passato il PUNTATORE a i. Per questo motivo prendono il valore attuale di i. Che se l'esecuzione è quella da me indicata: entrambi prendono il valore 1.
  • Re: Pthread_create passaggio di un valore intero

    Benissimo, allora devi fare come nell'esempio precedente che ti ho allegato.
    ovviamente nel multithread passeresti sempre lo stesso ptr, ma come ti gestisci un array
    di pthread_t devi usare un array di struct con dentro Id valore e quello che ti pare.
    ma l'esempio di prima lo hai guardato?
  • Re: Pthread_create passaggio di un valore intero

    Noi due non ci capiamo!
    Grazie lo stesso, per il tuo impegno.
  • Re: Pthread_create passaggio di un valore intero

    Ma guarda te cosa mi tocca scrivere con un cellulare...
    
    struct thread_info 
    {
      pthread_t id;
      int valore;
    };
    
    void *func(void *arg)
    {
      int valore=*(int *) arg;
      printf("valore=%d\n",valore);
    }
    
    int main()
    {
      struct thread_info tinfo[MAXTHREADS];
      int i;
      
      for(i = 0; i < MAXTHREADS; i++)
      {
        tinfo[i].valore=i;
        pthread_create(&tinfo[i].id, NULL, &func, &tinfo[i].valore);  
      }
    ...
    }
    
  • Re: Pthread_create passaggio di un valore intero

    
    pthread_create(&tid, NULL, &func, &valoreintero);
    ....
    void *func(void *arg){
    int val = *(int *) arg;
    }
    
    Qui ci vedevo ancora il problema.
    Ma nel codice che mi hai scritto tu, no!
    Effettivamente se salvi ogni i, in una struttura unica per il thread... non c'è nessun problema.

    Grazie

    Ho battuto molto sul primo esempio, insistendo che per me c'è condition code, per via di questo programma. Il cui risultato è che per tutti i 3 thread i = 0.
    
    #include <stdlib.h>
    #include <stdio.h>
    #include <errno.h>
    #include <pthread.h>
    #include <time.h>
    #define N 3
    #define TIMETHINKING 5
    #define TIMEEATING 10
    #define BEGIN -1
    #define THINKING 0
    #define HUNGRY 1
    #define EATING 2
    #define END 3
    pthread_mutex_t MutexTavolo = PTHREAD_MUTEX_INITIALIZER;
    pthread_cond_t Filosofo[N] = PTHREAD_COND_INITIALIZER;
    static int status_filos[N];
    void stamp_status(int id){
    	int i;
    	printf("Status (%d) : [",id);
    	for(i = 0; i < N; i++){
    		printf("%d",status_filos[i]);
    		if(i != (N-1)) printf(", ");
    		else printf("];\n");
    	}
    }
    void *filos(void *arg){
    	int i,timeoperation;
    	i = *(int *) arg;
    	srand(time(NULL));
    	/*FASE THINKING*/
    	pthread_mutex_lock(&MutexTavolo);
    			status_filos[i] = THINKING;
    			stamp_status(i);
    	pthread_mutex_unlock(&MutexTavolo);
    	timeoperation = rand()%TIMETHINKING + 1;
    	sleep(timeoperation);
    	pthread_mutex_lock(&MutexTavolo);
    	/*FASE HUNGRY*/
    			status_filos[i] = HUNGRY;
    			stamp_status(i);
    			while( (status_filos[(i-1)%N] == EATING) || (status_filos[(i+1)%N] == EATING) )
    				pthread_cond_wait(&Filosofo[i],&MutexTavolo);
    	/*FASE EATING*/
    			status_filos[i] = EATING;
    			stamp_status(i);
    	pthread_mutex_unlock(&MutexTavolo);
    	timeoperation = rand()%TIMEEATING + 1;
    	sleep(timeoperation);
    	/*FASE ENDING*/
    	pthread_mutex_lock(&MutexTavolo);
    		status_filos[i] = END;
    		stamp_status(i);
    		if( (status_filos[(i-1)%N] == HUNGRY) && (status_filos[(i-2)%N] != EATING) )
    			pthread_cond_signal(&Filosofo[(i-1)%N]);
    		if( (status_filos[(i+1)%N] == HUNGRY) && (status_filos[(i+2)%N] != EATING) )
    			pthread_cond_signal(&Filosofo[(i+1)%N]);
    	pthread_mutex_unlock(&MutexTavolo);	
    	pthread_exit( (void *) 17);
    }
    int main(){
    	int i;
    	pthread_t tid[N];
    	for(i = 0; i < N; i++)
    		status_filos[i] = BEGIN;
    	stamp_status(-1);
    	for(i = 0; i < N; i++){
    		printf("The philospher %d sits down on the table.\n",i);
    		pthread_create(&tid[i], NULL, &filos, &i);
    	}
    	for(i = 0; i < N; i++){
    		pthread_join(tid[i], NULL);
    		printf("The philospher %d rises from the table.\n",i);
    	}
    	return 0;
    }
    
  • Re: Pthread_create passaggio di un valore intero

    Usando lo struct il programma funziona
    grazie mille, e scusa per averti fatto dannare... stavo per rinunciare io, invece tu non hai rinunciato.. se ci fosse una votazione per questo forum ti voterei .


    Devo segnare che il post è stato risolto? come si fa?
Devi accedere o registrarti per scrivere nel forum
14 risposte