c++ bonne utilisation de mutex
j'ai multithread projet et j'ai couru à travers valgrind --tool=helgrind et il m'a montré quelques erreurs. Je suis l'aide de mutex il exaxtly comment je l'ai trouvé sur le net comment l'utiliser, pouvez vous s'il vous plaît me montrer quoi de mal?
#include <iostream>
#include <pthread.h>
#define MAX_THREADS 100
#define MAX_SESSIONS 100
static pthread_mutex_t M_CREATE_SESSION_LOCK= PTHREAD_MUTEX_INITIALIZER;
.....
void connection::proccess(threadVarsType &THREAD) {
....
pthread_mutex_lock(&M_CREATE_SESSION_LOCK);
unsigned int ii;
for (ii=0; ii<MAX_SESSIONS; ii++) {
if (SESSION[ii]==NULL) {
break;
}
}
if (ii==MAX_SESSIONS-1) {
....
pthread_mutex_unlock(&M_CREATE_SESSION_LOCK); //unlock session mutex
....
return;
} else {
....
pthread_mutex_unlock(&M_CREATE_SESSION_LOCK); //unlock session mutex
....
}
....
}
et les messages d'erreur:
==4985== Thread #1's call to pthread_mutex_lock failed
==4985== with error code 22 (EINVAL: Invalid argument)
....
==4985== Thread #1 unlocked an invalid lock at 0x4E7B40
==4985== at 0x32CD8: pthread_mutex_unlock (hg_intercepts.c:610)
....
==4985== Thread #1's call to pthread_mutex_unlock failed
==4985== with error code 22 (EINVAL: Invalid argument)
....
==4985== Thread #1's call to pthread_mutex_lock failed
==4985== with error code 22 (EINVAL: Invalid argument)
....
==4985== Thread #1 unlocked an invalid lock at 0x4E7B40
==4985== at 0x32CD8: pthread_mutex_unlock (hg_intercepts.c:610)
....
==4985== Thread #1's call to pthread_mutex_unlock failed
==4985== with error code 22 (EINVAL: Invalid argument)
Envisager d'utiliser Boost.Thread (boost.org/doc/libs/release/doc/html/thread.html) qui utilise les pthreads sous le capot. C'est tellement plus facile à travailler que le raw pthreads API.
je suis à la recherche de la solution la plus simple, parce que si je vais ajouter des millions bibliothèques ensuite, le programme sera 1000x plus lent et 100 de plus - et je n'apprendront rien 🙁
pthread est une interface C. Il n'a pas d'exceptions; ainsi, vous vérifiez les codes d'erreur lors de l'appel de ces fonctions.
Utilisation De Boost.Thread ne fera pas de votre programme de tellement plus grand, si vous avez un lien pour la version statique de la bibliothèque. Il ne sera également pas être considérablement plus lent. Pourquoi avez-vous de soins si votre programme se termine un peu ko plus grande? Le logiciel n'est plus distribué sur les disquettes de 1,44 MO, vous savez. Je suis désolé, mais vous avez peu de sérieux malentendus à propos de l'utilisation de bibliothèques telles un coup de pouce.
Si vous souhaitez utiliser le raw pthreads API à des fins d'apprentissage, je peux comprendre. Mais l'apprentissage pthreads ne va pas vous apprendre les notions fondamentales et les pièges de la programmation multithread. Ces concepts fondamentaux s'appliquent à de nombreux langages de programmation, quelle que soit la bibliothèque/interface utilisée pour le multithreading. Tout comme la façon dont l'apprentissage de l'assemblée de la langue ne va pas vous apprendre sur les structures de données et algorithmes.
je suis à la recherche de la solution la plus simple, parce que si je vais ajouter des millions bibliothèques ensuite, le programme sera 1000x plus lent et 100 de plus - et je n'apprendront rien 🙁
pthread est une interface C. Il n'a pas d'exceptions; ainsi, vous vérifiez les codes d'erreur lors de l'appel de ces fonctions.
Utilisation De Boost.Thread ne fera pas de votre programme de tellement plus grand, si vous avez un lien pour la version statique de la bibliothèque. Il ne sera également pas être considérablement plus lent. Pourquoi avez-vous de soins si votre programme se termine un peu ko plus grande? Le logiciel n'est plus distribué sur les disquettes de 1,44 MO, vous savez. Je suis désolé, mais vous avez peu de sérieux malentendus à propos de l'utilisation de bibliothèques telles un coup de pouce.
Si vous souhaitez utiliser le raw pthreads API à des fins d'apprentissage, je peux comprendre. Mais l'apprentissage pthreads ne va pas vous apprendre les notions fondamentales et les pièges de la programmation multithread. Ces concepts fondamentaux s'appliquent à de nombreux langages de programmation, quelle que soit la bibliothèque/interface utilisée pour le multithreading. Tout comme la façon dont l'apprentissage de l'assemblée de la langue ne va pas vous apprendre sur les structures de données et algorithmes.
OriginalL'auteur | 2011-04-29
Vous devez vous connecter pour publier un commentaire.
Abord, il faut toujours vérifier les valeurs de retour de vos appels de fonction. Si un pthread d'échec de l'appel, c'est un bon choix pour simplement appeler
abort()
qui va core dump, si vous avez activé ou tomber dans le débogueur si vous êtes en cours d'exécution avec un.Pthread appels de fonction vraiment ne doit jamais échouer, ce qui signifie que quelque chose de grave à votre programme. Dans un programme C ou C++ quelque chose qui provoque souvent des échecs mystérieux est une corruption de mémoire. Utiliser valgrind dans ses modes normaux pour vérifier qu'.
Une autre chose qui peut causer pthread appels à l'échec est de ne pas compiler à l'aide de
-pthread
. Si vous utilisez GCC, vous devez compiler et lier à l'aide de gcc avec une commande commegcc -pthread
. Qui fera le lien entre la bibliothèque pthread et il sera mis quelques préprocesseur qui peut être important pour votre système de fichiers d'en-tête.Certains systèmes réussi à compiler et lier un programme qui utilise pthread appels sans le lier à l'pthread bibliothèques. Ceci est fait de sorte qu'un programme ou une bibliothèque peut être thread-safe sans utilisation de threads. Le fil appels seront liés à factice fonctions, à moins que le véritable bibliothèque pthread est lié. Ce qui peut entraîner des appels de fonction à défaut.
Donc, assurez-vous que vous construisez avec les bonnes options de compilation pour inclure les pthread bibliothèques.
Une autre cause possible est que si vous êtes en s'appuyant sur certains buter-moitié-moitié hybride OS où il a commencé comme Linux 2.4 et ai mis à niveau vers Linux 2.6 NPTL à un certain point (j'ai travaillé sur quelque chose comme cette fois). Si vous tentez de compiler contre les anciens fichiers d'en-tête avec une ancienne définition de
PTHREAD_MUTEX_INITIALIZER
ou pas de la bonne taille pour le type depthread_mutex_t
alors que pourrait causer le problème.Faire bien que vous ajoutez
-pthread
à votre compiler flags.sa y
J'ai ajouté des vieux fichiers d'en-tête comme une cause possible.
#include <iostream> #include <pthread.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <fstream>
c'est tout ce que je suis en utilisantOriginalL'auteur Zan Lynx
Que l'erreur suggère quelque chose de mal avec l'initialisation du mutex. C'est dur de façon à ce que, mais assurez-vous que vous êtes l'initialiser dans le bon endroit.
Pouvez-vous publier la totalité du code? Il semble que le problème n'est pas dans le code que vous avez posté jusqu'à présent.
voici le code de test: codepad.org/LFbgYVbH mais le problème est que sur osx
OriginalL'auteur patrickvacek
Sur le Helgrind docs page, ils indiquent qu'il pourrait y avoir des faux positifs qui sont censés être supprimé ... en quelque sorte, vous pourriez être de heurter ceux depuis sur la surface, il ne semble pas comme vous êtes en utilisant pthread mutex de manière incorrecte.
Voici ce qu'ils écrivent:
Ils notent également que vous devriez être à l'aide d'une "prise en charge de la distribution Linux" ... ils ne parlent pas exactement ce que cela signifie, mais si vous êtes en utilisant un non-système d'exploitation Linux, qui pourrait peut-être aussi la cause de certains de ces "faux positifs". Il pourrait être intéressant de demander à l'équipe de développement afin de voir ce qu'ils disent à ce sujet.
ajouter une ligne à la
connection
classe qui ditstatic pthread_mutex_t M_CREATE_SESSION_LOCK;
, puis à l'intérieur de l' .fichier cpp, de modifier le mutex définition afin qu'il dit simplementpthread_mutex_t connection::M_CREATE_SESSION_LOCK = PTHREAD_MUTEX_INITIALIZER;
... Ou avez-vous besoin pour accéder à l'mutex en dehors de la classe?ne pas besoin de l'accès depuis l'extérieur de la classe.... mais même avec cette modification, le même résultat ;-( peut être que valgrind l'identification de quelque chose qui n'est pas l'erreur comme une erreur?
Je suis à jour de ma réponse ...
je vois.... il sera amusant de le déboguer ici 😉
OriginalL'auteur Jason
L'erreur
EINVAL
sur un appel àpthread_mutex_lock
signifie deux choses.The mutex was created with the protocol attribute having the value PTHREAD_PRIO_PROTECT and the calling thread's priority is higher than the mutex's current priority ceiling.
ou
The value specified by mutex does not refer to an initialised mutex object.
Le second semble plus probable. Essayez d'initialiser le mutex dans votre
main
fonction avecint error = pthread_mutex_init(&M_CREATE_SESSION_LOCK, NULL);
et vérifier si il y a une erreur, au lieu de l'initialiser avec la macro comme vous êtes actuellement.Êtes-vous éventuellement d'appel
pthread_mutex_destroy
à un certain point, avant d'appelerpthread_mutex_lock
?il est à seulement 4 occasions où j'manipuler avec
M_CREATE_SESSION_LOCK
- la création, la serrure, et 2 déverrouilleOriginalL'auteur Null Set