Maison  >  Article  >  Opération et maintenance  >  Il existe plusieurs méthodes pour la synchronisation des threads

Il existe plusieurs méthodes pour la synchronisation des threads

爱喝马黛茶的安东尼
爱喝马黛茶的安东尼original
2019-08-30 16:34:0614494parcourir

Il existe plusieurs méthodes pour la synchronisation des threads

Quelles sont les méthodes de synchronisation des threads ? Sous Linux, le système propose de nombreuses façons d'effectuer la synchronisation des threads, dont les plus couramment utilisées sont les verrous mutex, les variables de condition et les sémaphores. Il se peut que de nombreux partenaires ne soient pas familiers avec ces trois méthodes. en détails.

Trois méthodes pour réaliser la synchronisation des threads sous Linux :

1. Mutex (mutex)

Par le biais du mécanisme de verrouillage à réaliser. synchronisation entre les threads.

1. Initialisez le verrou. Sous Linux, le type de données mutex du thread est pthread_mutex_t. Avant utilisation, il doit être initialisé.

Allocation statique : pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

Allocation dynamique : int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutex_attr_t *mutexattr); 🎜 >2. Verrouiller. Pour accéder aux ressources partagées, le mutex doit être verrouillé. Si le mutex est déjà verrouillé, le thread appelant se bloquera jusqu'à ce que le mutex soit déverrouillé.

int pthread_mutex_lock (pthread_mutex *mutex);

int pthread_mutex_trylock (pthread_mutex_t *mutex);

3. Après avoir terminé l'accès à la ressource partagée, le mutex doit être déverrouillé.

int pthread_mutex_unlock (pthread_mutex_t *mutex);

4. Une fois le verrou utilisé, il doit être détruit pour libérer des ressources.

int pthread_mutex_destroy(pthread_mutex *mutex);

#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <pthread.h>
#include "iostream"
using namespace std;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int tmp;
void* thread(void *arg)
{
cout << "thread id is " << pthread_self() << endl;
pthread_mutex_lock(&mutex);
tmp = 12;
cout << "Now a is " << tmp << endl;
pthread_mutex_unlock(&mutex);
return NULL;
}
int main()
{
pthread_t id;
cout << "main thread id is " << pthread_self() << endl;
tmp = 3;
cout << "In main func tmp = " << tmp << endl;
if (!pthread_create(&id, NULL, thread, NULL))
{
cout << "Create thread success!" << endl;
}
else
{
cout << "Create thread failed!" << endl;
}
pthread_join(id, NULL);
pthread_mutex_destroy(&mutex);
return 0;
}
//编译:g++ -o thread testthread.cpp -lpthread

Recommandations associées : "
Tutoriel de démarrage PHP

"

2. Les variables de condition (cond)

sont différentes des verrous mutex. Les variables de condition sont utilisées pour attendre au lieu de verrouiller. Les variables de condition sont utilisées pour bloquer automatiquement un thread jusqu'à ce qu'une situation particulière se produise. Habituellement, les variables de condition et les verrous mutex sont utilisés ensemble. Les variables de condition sont divisées en deux parties : les conditions et les variables. La condition elle-même est protégée par un mutex. Le thread doit verrouiller le mutex avant de modifier l'état conditionnel. Les variables de condition nous permettent de dormir et d'attendre qu'une certaine condition se produise. Les variables de condition sont un mécanisme de synchronisation utilisant des variables globales partagées entre les threads. Elle comprend principalement deux actions : un thread attend que « la condition de la variable de condition soit vraie » et se bloque ; que la condition est vraie) Signal). La détection des conditions est effectuée sous la protection d'un verrou mutex. Si une condition est fausse, un thread bloque et libère automatiquement le mutex en attendant que l'état change. Si un autre thread modifie la condition, il signale la variable de condition associée, réveille un ou plusieurs threads qui l'attendent, réacquiert le mutex et réévalue la condition. Si deux processus partagent une mémoire lisible et inscriptible, des variables de condition peuvent être utilisées pour réaliser la synchronisation des threads entre les deux processus.

1. Initialiser les variables de condition.

Initialisation statique, pthread_cond_t cond = PTHREAD_COND_INITIALIER;

Initialisation dynamique, int pthread_cond_init (pthread_cond_t *cond, pthread_condattr_t *cond_attr); 🎜 > 2. Attendez que les conditions soient établies. Relâchez le verrou et bloquez en attendant que la variable de condition soit vraie. timewait() définit le temps d'attente, et s'il n'y a pas de signal, retourne à ETIMEOUT (le verrouillage garantit qu'il n'y a qu'un seul thread en attente)

int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex);

int pthread_cond_timewait (pthread_cond_t *cond, pthread_mutex *mutex, const timespec *abstime);3. Activer les variables de condition. pthread_cond_signal, pthread_cond_broadcast (activer tous les threads en attente)

int pthread_cond_signal (pthread_cond_t *cond);

int pthread_cond_broadcast (pthread_cond_t *cond); >

4. Effacez la variable de condition. Aucun thread n'attend, sinon EBUSY


int pthread_cond_destroy (pthread_cond_t *cond);

Comme les processus, les threads peuvent également communiquer via des sémaphores, bien qu'ils soient légers. Les noms des fonctions sémaphores commencent tous par "sem_". Il existe quatre fonctions de sémaphore de base utilisées par les threads.

1. Initialisation du sémaphore.

int sem_init (sem_t *sem, int pshared, unsigned int value)

Il s'agit d'initialiser le sémaphore spécifié par sem et de configurer son option de partage (linux ne prend en charge que 0, ce qui signifie qu'il s'agit d'un sémaphore local du processus en cours), puis donnez-lui une valeur initiale VALEUR.

2. Attendez le sémaphore. Décrémentez le sémaphore de 1 et attendez que la valeur du sémaphore soit supérieure à 0.

int sem_wait (sem_t *sem);


3. Augmentez la valeur du sémaphore de 1. Et informez les autres fils de discussion en attente.


int sem_post (sem_t *sem);


4. Nous nettoyons le sémaphore après l'avoir utilisé. Renvoyez toutes les ressources possédées.


int sem_destroy (sem_t *sem);


[cpp] view plain copy
#include <stdio.h>
#include <pthread.h>
#include "stdlib.h"
#include "unistd.h"
pthread_mutex_t mutex;
pthread_cond_t cond;
void hander(void *arg)
{
free(arg);
(void)pthread_mutex_unlock(&mutex);
}
void *thread1(void *arg)
{
pthread_cleanup_push(hander, &mutex);
while(1)
{
printf("thread1 is running\n");
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex);
printf("thread1 applied the condition\n");
pthread_mutex_unlock(&mutex);
sleep(4);
}
pthread_cleanup_pop(0);
}
void *thread2(void *arg)
{
while(1)
{
printf("thread2 is running\n");
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex);
printf("thread2 applied the condition\n");
pthread_mutex_unlock(&mutex);
sleep(1);
}
}
int main()
{
pthread_t thid1,thid2;
printf("condition variable study!\n");
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL);
pthread_create(&thid1, NULL, thread1, NULL);
pthread_create(&thid2, NULL, thread2, NULL);
sleep(1);
do
{
pthread_cond_signal(&cond);
}while(1);
sleep(20);
pthread_exit(0);
return 0;
}

Voici les trois méthodes couramment utilisées pour réaliser la synchronisation des threads sous Linux. Comme nous le savons tous, le plus gros point fort. des threads Il s'agit du partage de ressources, et le problème de synchronisation des threads dans le partage de ressources est une difficulté majeure.

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn