2010-06-04 10 views
6

Je viens de commencer l'apprentissage API pthreads et je suis suivant le tutoriel hereEst-il légitime de passer un argument comme nul *?

Cependant, dans un exemple de programme de pthread_create, le programme d'échantillonnage crée une variable longue et passe sa valeur, typecasted comme void*. Dans la fonction d'entrée de fil, il le déréférence tout comme un long.

Est-ce légitime? Je comprends si je passe l'adresse de la variable t, chaque thread agirait sur la même variable et non sur une copie de celui-ci. Pouvons-nous faire cela parce que c'est un void* et le compilateur n'a aucune idée du type que nous envoyons?

#include <pthread.h> 
#include <stdio.h> 

#define NUM_THREADS  5 

void *PrintHello(void *threadid) 
{ 
    long tid; 
    tid = (long)threadid; 
    printf("Hello World! It's me, thread #%ld!\n", tid); 
    pthread_exit(NULL); 
} 

int main (int argc, char *argv[]) 
{ 
    pthread_t threads[NUM_THREADS]; 
    int rc; 
    long t; 
    for(t=0; t<NUM_THREADS; t++){ 
     printf("In main: creating thread %ld\n", t); 
     rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t); 
     if (rc){ 
     printf("ERROR; return code from pthread_create() is %d\n", rc); 
     exit(-1); 
     } 
    } 
    pthread_exit(NULL); 
} 
+0

Donc, votre question concerne la validité de cast ou la validité du pointeur de passage en tant que 4ème argument pour pthread_create()? – qrdl

+0

@qrdl: en fait c'est les deux mais j'étais plus intéressé par le passage long comme 4ème argument pour pthread_create faisant complier pense que vous envoyez réellement une adresse. –

Répondre

4

Cela fonctionne aussi longtemps que sizeof(long) <= sizeof(void*), et que chaque valeur de long peut être représentée comme void*.

Mieux serait de passer l'adresse de la variable. Vous pouvez lancer à partir d'un T* à void*, et vice versa sans risque et sans hypothèse.

+1

@Charles 'sizeof (void)' et 'sizeof (void *)' sont des bêtes différentes – qrdl

+0

@qrdl: Vous avez raison! –

4

C'est aussi légitime que n'importe quel type de typecasting. Le point est que rien ne peut être fait avec la valeur de l'argument, jusqu'à ce qu'il soit classé, donc tid = (long)threadid.

Vérifiez l'ancien Q & A When to use a void pointer?.

+0

Vous dites, 'void * 'veut dire" pointeur vers quelque chose ", mais que" quelque chose "doit être défini avant de pouvoir être utilisé, non? – Abel

+0

@Abel: droite. Le point est lorsque vous voulez faire quelque chose avec un pointeur qui ne peut pas recevoir les informations de type. –