Le système Linux est un système d'exploitation qui prend en charge l'exécution simultanée de tâches multiples. Il peut exécuter plusieurs processus en même temps, améliorant ainsi l'utilisation et l'efficacité du système. Cependant, s'il existe plusieurs threads dans un processus et que ces threads doivent partager certaines données ou ressources, une incohérence des données ou une concurrence entre les ressources peuvent se produire, entraînant des erreurs ou des exceptions système. Afin de résoudre ce problème, certains mécanismes de synchronisation doivent être utilisés, tels que les sémaphores, les variables de condition, les mutex, etc. Parmi eux, un mutex est un mécanisme de synchronisation relativement simple et efficace. Il permet à un thread de verrouiller des données ou des ressources partagées lors de leur accès pour empêcher d'autres threads d'y accéder en même temps, garantissant ainsi la sécurité des threads. Cet article expliquera en détail la méthode de synchronisation du mutex Mutex dans Linux multi-threads, y compris l'initialisation, le verrouillage, le déverrouillage et la destruction du mutex.
Sous Linux, le type de données mutex du thread est pthread_mutex_t Avant utilisation, il doit être initialisé :
.Pour un mutex alloué statiquement, vous pouvez le définir sur PTHREAD_MUTEX_INITIALIZER ou appeler pthread_mutex_init.
Pour les mutex alloués dynamiquement, après avoir demandé de la mémoire (malloc), il est initialisé via pthread_mutex_init, et pthread_mutex_destroy doit être appelé avant de libérer la mémoire (gratuite).
Prototype :
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
int pthread_mutex_destroy(pthread_mutex_t *mutex);
Fichier d'en-tête :
Valeur de retour : 0 en cas de succès, numéro d'erreur si une erreur se produit.
Remarque : si vous utilisez les attributs par défaut pour initialiser le mutex, définissez simplement attr sur NULL. D'autres valeurs seront expliquées plus tard.
.Pour accéder aux ressources partagées, vous devez verrouiller le mutex. Si le mutex est déjà verrouillé, le thread appelant se bloquera jusqu'à ce que le mutex soit déverrouillé. Après avoir terminé l'accès aux ressources partagées, vous devez verrouiller l'exclusion pour déverrouiller. .
Parlons de la fonction de verrouillage :
Fichier d'en-tête :
Prototype :
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
Valeur de retour : 0 en cas de succès, numéro d'erreur si une erreur se produit.
Explication : Parlons spécifiquement de la fonction trylock. Cette fonction est un mode d'appel non bloquant, c'est-à-dire que si le mutex n'est pas verrouillé, la fonction trylock verrouillera le mutex et accédera aux ressources partagées ; le mutex n'est pas verrouillé, la fonction trylock verrouillera le mutex et accédera aux ressources partagées. L'exclusivité est verrouillée, et la fonction trylock ne bloquera pas et n'attendra pas mais renverra directement EBUSY, indiquant que la ressource partagée est occupée.
Parlons encore de la fonction solution :
Fichier d'en-tête :
Prototype : int pthread_mutex_unlock(pthread_mutex_t *mutex
);Valeur de retour : 0 en cas de succès, numéro d'erreur si une erreur se produit.
3. Impasse :
Un blocage se produit principalement lorsqu'il existe plusieurs verrous dépendants et se produit lorsqu'un thread tente de verrouiller le mutex dans l'ordre opposé à celui d'un autre thread. La façon d'éviter un blocage est une chose à laquelle il convient d'accorder une attention particulière lors de l'utilisation de mutex.
D'une manière générale, il existe plusieurs principes de base non écrits :
Assurez-vous d'obtenir un verrou avant d'opérer sur des ressources partagées.
Assurez-vous de déverrouiller le verrou après avoir terminé l'opération.
S'il y a plusieurs verrous, si l'ordre d'acquisition est ABC, l'ordre de libération doit également être ABC.
Un thread doit libérer le verrou qu'il a acquis lorsqu'il renvoie une erreur.
Exemple :
#include #include #include #include #include pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; int lock_var; time_t end_time; int sum; void pthread1(void *arg); void pthread2(void *arg); void pthread3(void *arg); int main(int argc, char *argv[]) { pthread_t id1,id2,id3; pthread_t mon_th_id; int ret; sum=10; end_time = time(NULL) 10; pthread_mutex_init(&mutex,NULL); ret=pthread_create(&id1,NULL,(void *)pthread1, NULL); if(ret!=0) perror("pthread cread1"); ret=pthread_create(&id2,NULL,(void *)pthread2, NULL); if(ret!=0) perror("pthread cread2"); ret=pthread_create(&id3,NULL,(void *)pthread3, NULL); if(ret!=0) perror("pthread cread3"); pthread_join(id1,NULL); pthread_join(id2,NULL); pthread_join(id3,NULL); exit(0); } void pthread1(void *arg) { int i; while(time(NULL) if(pthread_mutex_lock(&mutex)!=0) //lock { perror("pthread_mutex_lock"); } else printf("pthread1:pthread1 lock the variablen"); for(i=0;iif(pthread_mutex_unlock(&mutex)!=0) //unlock { perror("pthread_mutex_unlock"); } else printf("pthread1:pthread1 unlock the variablen"); sleep(1); } } void pthread2(void *arg) { int nolock=0; int ret; while(time(NULL) if(ret==EBUSY) printf("pthread2:the variable is locked by pthread1n"); else{ if(ret!=0) { perror("pthread_mutex_trylock"); exit(1); } else printf("pthread2:pthread2 got lock.The variable is %dn",lock_var); if(pthread_mutex_unlock(&mutex)!=0)//unlock { perror("pthread_mutex_unlock"); } else printf("pthread2:pthread2 unlock the variablen"); } sleep(1); } } void pthread3(void *arg) {/* int nolock=0; int ret; while(time(NULL) if(ret==EBUSY) printf("pthread3:the variable is locked by pthread1 or 2n"); else { if(ret!=0) { perror("pthread_mutex_trylock"); exit(1); } else printf("pthread3:pthread3 got lock.The variable is %dn",lock_var); if(pthread_mutex_unlock(&mutex)!=0) { perror("pthread_mutex_unlock"); } else printf("pthread3:pthread2 unlock the variablen"); } sleep(3); }*/ }
Cet article explique en détail la méthode de synchronisation du mutex Mutex dans Linux multi-threads, y compris l'initialisation, le verrouillage, le déverrouillage et la destruction du mutex. En comprenant et maîtrisant ces connaissances, nous pouvons mieux utiliser les mutex pour réaliser la synchronisation entre plusieurs threads et améliorer la stabilité et l'efficacité du système.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!