Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 23/05/2017, à 23:49

DonutMan75

[RESOLU] [C] Passer proprement un int à un thread

Bonjour à tous,
encore désolé pour le dérangement sur le langage C mais je bloque à nouveau sur une petite question ^^
Je lis en ce moment le livre de Christophe Blaess sur le développement système sous Linux (super bien ! très instructif !).

Dans son chapitre sur les threads, il lance NTHREAD successifs à l'aide d'une boucle sur une variable i (i=0, 1,... NTHREAD-1) et leurs passe la variable i afin que ces threads puissent afficher quelque chose comme "Bonjour je suis le thread n°k"

Voici le code (simplifié) :

int main(void)
	{
	int i;
	pthread_t thread;

	
	printf("Je suis le PERE\n");

	
	for(i=0;i<NTHREAD;i++)
		{
		pthread_create(&thread, NULL, hello, (void *)i);
		}
	
	sleep(10);
	}

void *hello(void *arg)
	{
	int n = (int) arg;
	printf("Je suis le THREAD-%02d\n", n);
	}

Bon, ce qui me choque un peu la-dedans c'est le cast violent pour passer l'argument i dans pthread_create : "(void *) i"
Puis le cast en sens inverse dans la fonction hello : "int n = (int) arg;"

Christophe Blaess indique :

C. Blaess, Développement Système sous Linux, p.160 a écrit :

Lors de l'appel à pthread_create(), on peut fournir en dernier paramètre une valeur (un pointeur générique de type void* ou toute donnée compatible), que le thread trouvera en argument de sa fonction principale. Voyons un exemple où nous forçons un transtypage (cast) d'un entier en pointeur générique. Cette conversion est possible sur toutes les architectures supportant Linux.

A la compilation, le compilateur gueule un peu et lève quelques warnings mais enfin, ça semble marcher....

Je pensais modifier cela par (je ne recopie que les deux lignes en questions) :

// Dans le main
int table[NTHREAD];

[...]
// Dans la boucle
*(table+i) = i;
pthread_create(&thread, NULL, hello, (void *) (table +i));
[...]

// Dans la fonction hello
int n = (int) *((int *) arg);

En gros, on cast simplement un pointeur générique vers un pointeur sur int. C'est déjà plus propre et le compilo ne moufte pas !

Oui mais... Comme la variable i est susceptible d'être modifée dans le temps, il faut stocker sa valeur à chaque itération dans un tableau. C'est l'adresse du i-ème élement de ce tableau que je passe ensuite en argument de hello.

Ma question est : quelle est la meilleure solution ??

Le cast (void *) --> (int) est super simple à gérer mais soulève des warnings... Conseillerez-vous néanmoins cette solution ?
L'utilisation de tableau est un peu plus lourde mais ne génère aucun warning...

Merci d'avance, j'aimerais prendre les bons réflexes le plus tôt possible ^^

Bonne journée smile

Donut

Dernière modification par DonutMan75 (Le 24/05/2017, à 15:04)

Hors ligne

#2 Le 24/05/2017, à 07:24

alduc31

Re : [RESOLU] [C] Passer proprement un int à un thread

Salut DonutMan75,

C'est un petit exemple où l'auteur n'a pas voulu s’embêter pour transmettre la valeur de i en la mettant dans le seul argument du thread *int. Ca fonctionne si le codeur sait ce qu'il fait.
Le compilateur gcc est devenu de moins tolérant à ce genre d'arrangement.
Utiliser une variable int qui contient la valeur de i et passer son adresse au thread comme tu fais est préférable pour éviter par exemple une mauvaise compréhension de quelqu'un qui lirait ton code.
Prendre soin d'analyser les warnings du compilateur et les supprimer est une très bonne chose. Une tendance risquée quand on commence à programmer est de penser que des warnings c'est pas grave ce qui dans certain cas n'est pas vrai (warning sur l'utilisation d'une variable non initialisée par exemple).


Asus UX325EA oled (i5-1135G7,16Go) avec Lunar 23.04 (base xubuntu modifiée)

Hors ligne

#3 Le 24/05/2017, à 15:03

DonutMan75

Re : [RESOLU] [C] Passer proprement un int à un thread

Hello alduc31,
merci pour ton éclairage.
Du coup, je pense que je vais rester le plus possible en programmation "sans warning" plutôt que de m'éloigner des chemins battus smile

Donut

Hors ligne