Salut,
Je suis en train de jeter un œil sur pthread (oui je sais C++11 arrive c'est plus la peine)
Mais le bon usage des mutex n'est pas clair pour moi
pthread_mutex_lock(&monmutex) : Si je comprend bien, lorsque plusieurs threads vérouillent le mutex, les autres se mettent en attente jusqu'à c que le mutex soit libéré ?
pthread_cond_wait(signal,mutex) Va créer une sorte de slot qui attend un signal et va simplement attendre le signal, mais à quoi sert le mutex ? Est-ce que je dois faire référence au mutex avant d’appeler ma fonction ?
Est-ce que je peux locker un stream avec un mutex ? i.e. contrôler l'écriture sur cout ?
Voilà un bout de code, qui se contente d'afficher le contenu d'un vecteur d'entier, ça tourne, je soupçonne qu'il reste un heisenbug à l'intérieur, mais surtout j'ai mis mes lock un peu au hasard et j'aimerais faire ça proprement,
Le but du code est simple, j'ai un thread mère qui itére le vecteur et lance des threads filles qui ici se contente d'afficher le contenu du vecteur, sachant que je veux un nombre donnés de threads filles.
//Nthread, mutex_* cond_* sont des globales, c'est moche, mais pour un test c'est rapide
void* Mythread2(void* data) {
//Ici par intéret pédago, on se contente d'afficher un entier, mais la tache pourrait être plus complexes
pthread_mutex_lock(&mutex_outlock);
//Est-ce que ça locke cout ? apparement non
cout << ">> >> "<< *(reinterpret_cast<int*>(data)) << endl;
pthread_mutex_unlock(&mutex_outlock);
pthread_mutex_lock(&mutex_launchnew);
//Le thread est presque finit on décrémente le compteur de thread
Nthread--;
pthread_cond_signal (&cond_launch);
pthread_mutex_unlock(&mutex_launchnew);
}
void* MotherThread(void* data) {
//L'idée c'est d'avoir un thread qui s'assure qu'on utilise pas plus de threads que ce que l'on veut
const int MaxThread=4;
//C'est pas très C++ mais apparemement c'est ce que veut pthread
vector<int>* params=reinterpret_cast<vector<int>* >(data);
vector<int>::iterator iter=params->begin();
while (Nthread<MaxThread) {
if (iter==params->end()) break;
pthread_t thread;
int* pval=NULL;
pval=&(*iter);
pthread_create(&thread, NULL,Mythread2, reinterpret_cast<void*>(pval));
++Nthread;
++iter;
}
while (iter!=params->end()) {
//Ici je veux locker mon compteur de threads pour garder un nombre
//constants de threads qui tournent
pthread_mutex_lock(&mutex_launchnew);
pthread_t thread;
//On va attendre qu'un thread soit finit pour en lancer un autre
// C'est surement plus éléguant qu'un while(true)
pthread_cond_wait(&cond_launch,&mutex_launchnew);
while (Nthread<MaxThread) {
int* pval=NULL;
pval=&(*iter);
pthread_create(&thread, NULL,Mythread2, reinterpret_cast<void*>(pval));
Nthread++;
++iter;
cout << "Starting new thread, at the moment there is " << Nthread << "running" << endl;
}
//On a lancé le thread on peut dévérouiller
pthread_mutex_unlock(&mutex_launchnew);
}
}
En relisant le code, j'ai 2-3 doutes qui viennent,
- Si un thread se finit alors que mon autre thread tourne déjà, que devient le slot qui attend la fin d'un thread pour en lancer un ? J'imagine que le while est une solution au problème cas si je manque la fin d'un thread je serais avertit lorsque le prochain se termine.
- Il y a pas un moyen plus éléments de compter le nombre de thread en cours ? car incrémenter/décrementer un compteur c'est moche
merci pour vos conseils/commentaires
# E_NOVALID
Posté par fcartegnie . Évalué à 2.
La réponse à tes questions est tout simplement que ta manière de faire n'est pas valide.
[^] # Re: E_NOVALID
Posté par Mais qui suis-je ? :) . Évalué à 1.
J'ai bien pensé à pthread_join, mais d'après ce que j'ai compris
pthread_join stoppe le programme jusqu'à ce que le thread joigne, donc si j'ai 4 Threads (numéroté de 1 à 4), pendant que j'attends que le thread 1 soit finit, les threads 3 et 4 vont se finir et je ne détecterais leurs fin que lorsque le thread 1 sera finit,
il y a bien pthread_tryjoin_np, mais ça me force de toute façon soit à avoir une boucle qui tourne en attendant qu'il se passe quelques chose, soit à intercepter un message,
Questions bonus, pthread_tryjoin_np c'est non portable à quel point ? Ça marche chez moi, je suppose aussi sous win win, et quid du reste ?
Bref cette version est elle vraiment meilleure ? c'est vrai qu'elle est plus courte pour le même résultat et se passe de mutex et autres globales, mais j'ai l'impression que je vais devoir les rajouter
}
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.