2010-11-19 19 views
4

J'essaie d'apprendre sur C multithreading, et j'ai vu quelques choses rares. Je comprends que passer des paramètres à un thread doit être fait avec des pointeurs. J'ai trouvé un exemple que je ne comprends pas. Je vais copier les lignes pertinentes:Comment passer des paramètres à un thread dans c multithread correctement

pthread_t tid[MAX_THREADS] 
int n_veg 
pthread_create(&tid[n],NULL,caracter,(void *)n_veg) 

caracter est évidemment une fonction pré-déclarée.

Maintenant, pourquoi utilisons-nous un casting de pointeur void au lieu d'un casting de pointeur int? Y a-t-il une différence pertinente?

Deuxièmement, pourquoi utilisons-nous un moulage de pointeur en premier lieu? Ne pouvons-nous pas utiliser "& n_veg" comme avec le premier paramètre?

Merci d'avance.

Répondre

10

Comme vos deux questions sont liées, je vais y répondre ensemble: pthread_create prend un void * paramètre, de sorte que vous pouvez vraiment passer dans n'importe quel pointeur que vous voulez. Dans ce cas, cependant, nous ne passons pas de pointeur, mais seulement une valeur entière simple convertie en pointeur. Cela signifie que vous y accéder comme ça dans caracter:

int value = (int)n_veg; 

Comme vous l'avez mentionné, vous pouvez très bien passer un pointeur réel &n_veg et récupérer la valeur comme ceci:

int value = *(int *)n_veg; 

En fait, Dans la plupart des cas, vous devrez transmettre plus de données qu'un simple entier, comme une structure, et dans ce cas, devez passer un pointeur, car vous ne pouvez pas simplement le transformer en pointeur comme un entier. Une chose à garder à l'esprit lorsque vous passez un pointeur est que n_veg ne doit pas sortir de la portée tant que le thread est en cours d'exécution. Par exemple, si vous faites:

void test() { 
    int n_veg; 
    pthread_create(&tid[n],NULL,caracter,&n_veg); 
} 

alors &n_veg sera invalide dès que test retours, mais le fil peut encore être en cours d'exécution et sera la tenue d'une adresse non valide. Pour cette raison, les structures passées aux threads sont normalement allouées dynamiquement, par exemple en utilisant malloc, et le thread peut free une fois qu'il a terminé.

+0

Donc, y a-t-il une réelle différence entre passer un vrai pointeur ou lancer la valeur si on travaille avec des entiers? Et, pourquoi * (int *) n_veg? Je suis désolé si cette deuxième question est stupide, c'est ma deuxième année sur la programmation et j'avais seulement utilisé java jusqu'à cette semaine:/ – bluehallu

+1

@Hallucynogenyc: Oui il y a. Si vous passez dans un vrai pointeur, vous pouvez changer la valeur d'origine en utilisant le pointeur.À propos de '* (int *) n_veg': pour utiliser un 'void *', vous devez convertir un type réel, d'où le '(int *)', puis le '*' déréférence le pointeur pour obtenir la valeur. – casablanca

+0

Tout est clair. Merci beaucoup! – bluehallu

0

pthread_create est défini comme suit:

int pthread_create(pthread_t *restrict thread, const pthread_attr_t *restrict attr, 
    void *(*start_routine)(void *), void *restrict arg); 

Il attend un void * que son dernier paramètre. Si vous omettez la distribution, le compilateur vous avertira.

+0

Oh, c'est juste que la méthode le demande ... Je pensais que les pointeurs de vide étaient opérés de manière transparente à la méthode. Oublie. – bluehallu