0
votes

pthread_join et avidité ** - Erreur de compréhension

J'ai écrit une tâche simple comme ci-dessous. Il imprime une chaîne, incrémente la variable globale globale et renvoie sa valeur, via Pthread_exit, à la pthread_join. xxx pré>

Le compilateur me donne l'erreur: p>

main.c: In function ‘main’:
main.c:29:2: warning: ‘ppvglob’ may be used uninitialized in this function [-Wmaybe-uninitialized]
   29 |  pthread_join(tid, ppvglob);
      |  ^~~~~~~~~~~~~~~~~~~~~~~~~~


1 commentaires

Votre rappel de Pthread doit avoir le format Void * F (vide *) et rien d'autre. Les fonctions qui renvoient une valeur doivent en réalité retourner aussi.


3 Réponses :


2
votes

Lorsque vous faites:

% gcc -Wall c.c -lpthread
% ./a.out
I am a simple thread.
Variabile globale restituita alla terminazione del thread: 1


6 commentaires

Bonjour @bruno, pourriez-vous m'expliquer comment venir et pvglob est initialisé s'il vous plaît? Je ne l'ai jamais utilisé auparavant et le pthread_exit retourne un vide *, à la place & pvglob est un vide **. Peut-être que le pthread_exit à l'intérieur fait une conversion de Void * en vide ** et le transmettre à la pthread_join?


@Gennaroarguzzi pvglob est défini avec l'état de sortie du filetage cible (c.-à-d. La valeur que le fil cible fournie à pthread_exit), si le thread cible a été annulé, puis par pthread_canceled (voir man7.org/linux/man-pages/man3/pthread_join.3.html ). Donc, dans votre cas, vous obtiendrez la valeur de glob


@Gennaroarguzzi Il n'y a pas de conversion de Void ** à Void * , le deuxième argument de pthread_join est un pointeur pour permettre à la fonction de définir la fonction Valeur, dans ce cas, le pointeur pointe vers un vide * car il s'agit du type de retour de la fonction Toplevel du fil / défini par pthread_exit . Supposant que la fonction de toplevel d'un thread renvoie un int puis pthread_exit obtenez un int Pour être cohérent, puis pthread_join a Pour obtenir un int *


Je n'ai qu'un doute: pourquoi le compilateur dit-il que le «PPVGLOB» peut être utilisé ininitialisé? Il est ininitialisé parce que je ne l'ai jamais utilisé auparavant.


@Gennaroarguzzi Il est ininitialisé parce que vous utilisez sa valeur avant de la définir. void ** ppvglob; définit ppvglob sans l'initialisation. Si c'est une variable globale, elle est initialisée par NULL par défaut, mais dans votre cas, il s'agit d'une variable locale, donc aucune initialisation par défaut


@Gennaroarguzzi mais donnant son adresse ( & pvglob ) sa valeur n'est pas utilisée à ce niveau et le fait qu'il n'est pas initialisé n'est pas pertinent => aucun avertissement



0
votes

pthread_join () a un paramètre void ** car il doit mettre à jour un EXISTANT VOID * .
C'est la même logique que fournir et int * à scanf ("% d", ...) : pour mettre à jour un int vous besoin de fournir son adresse.
Dans le cas général, lorsqu'une fonction C doit mettre à jour un type existant , Ensuite, il a besoin d'un paramètre type * .

Dans tous les cas, vous ne déclarez pas simplement un type non initialisé * mais Fournissez l'adresse ( & ) d'un type existant .
Donc, ici, vous devez prendre l'adresse d'un vide * de sorte que Le paramètre est initialisé à un emplacement où un void * se tient réellement.


0 commentaires

0
votes

L'idée ici est d'avoir un vide * code> ... xxx pré>

... et de transmettre son adresse em> à pthread_join () code> La fonction peut donc indiquer la valeur "retour" ... p> xxx pré>

ceci "rendant le point" valeur "nécessite pthread_join () code> à Dérenceference em> son paramètre ... p> xxx pré>

... donc que Votre em> glob code> aura changé sa valeur. P>

Que vous em> a déclaré ... P>

void * glob;

/* ... */

pthread_join(tid, &glob);

int * v = (int*)glob;
printf("Variabile globale restituita alla terminazione del thread: %d\n", *v);                   


0 commentaires