Heim  >  Artikel  >  Betrieb und Instandhaltung  >  Es gibt verschiedene Methoden zur Thread-Synchronisierung

Es gibt verschiedene Methoden zur Thread-Synchronisierung

爱喝马黛茶的安东尼
爱喝马黛茶的安东尼Original
2019-08-30 16:34:0614410Durchsuche

Es gibt verschiedene Methoden zur Thread-Synchronisierung

Welche Methoden gibt es zur Thread-Synchronisierung? Unter Linux bietet das System viele Möglichkeiten, eine Thread-Synchronisation zu erreichen. Die am häufigsten verwendeten sind Mutex-Sperren, Bedingungsvariablen und Semaphoren. Möglicherweise sind viele Partner mit diesen drei Methoden nicht vertraut ausführlich.

Drei Methoden zum Erreichen der Thread-Synchronisation unter Linux:

1. Mutex (Mutex)

Durch Sperrmechanismus zu erreichen Synchronisation zwischen Threads.

1. Initialisieren Sie die Sperre. Unter Linux ist der Mutex-Datentyp des Threads pthread_mutex_t. Vor der Verwendung muss es initialisiert werden.

Statische Zuweisung: pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

Dynamische Zuweisung: int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutex_attr_t *mutexattr);

2. Sperren. Um auf gemeinsam genutzte Ressourcen zuzugreifen, muss der Mutex gesperrt sein. Wenn der Mutex bereits gesperrt ist, blockiert der aufrufende Thread, bis der Mutex entsperrt wird.

int pthread_mutex_lock (pthread_mutex *mutex);

int pthread_mutex_t *mutex);

3. Nach Abschluss des Zugriffs auf die gemeinsam genutzte Ressource muss der Mutex entsperrt werden.

int pthread_mutex_unlock (pthread_mutex_t *mutex);

4. Zerstöre die Sperre. Nachdem die Sperre verwendet wurde, muss sie zerstört werden, um Ressourcen freizugeben.

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

Verwandte Empfehlungen: „PHP Getting Started Tutorial

2. Bedingungsvariablen (cond)

unterscheiden sich von Mutex-Sperren. Bedingungsvariablen werden zum Warten statt zum Sperren verwendet. Bedingungsvariablen werden verwendet, um einen Thread automatisch zu blockieren, bis eine besondere Situation eintritt. Normalerweise werden Bedingungsvariablen und Mutex-Sperren zusammen verwendet. Bedingungsvariablen sind in zwei Teile unterteilt: Bedingungen und Variablen. Die Bedingung selbst ist durch einen Mutex geschützt. Der Thread muss den Mutex sperren, bevor er den bedingten Zustand ändert. Bedingungsvariablen ermöglichen es uns, zu schlafen und darauf zu warten, dass eine bestimmte Bedingung eintritt. Bedingungsvariablen sind ein Mechanismus zum Synchronisieren mithilfe globaler Variablen, die von Threads gemeinsam genutzt werden. Sie umfassen hauptsächlich zwei Aktionen: Ein Thread wartet darauf, dass „die Bedingung der Bedingungsvariablen wahr ist“, und der andere Thread stellt fest, dass „die Bedingung wahr ist“. dass die Bedingung wahr ist) Signal). Die Erkennung von Bedingungen erfolgt unter dem Schutz einer Mutex-Sperre. Wenn eine Bedingung falsch ist, blockiert ein Thread automatisch den Mutex und gibt ihn frei, während er darauf wartet, dass sich der Status ändert. Wenn ein anderer Thread die Bedingung ändert, signalisiert er die zugehörige Bedingungsvariable, weckt einen oder mehrere darauf wartende Threads auf, ruft den Mutex erneut ab und wertet die Bedingung erneut aus. Wenn zwei Prozesse den lesbaren und beschreibbaren Speicher gemeinsam nutzen, können Bedingungsvariablen verwendet werden, um eine Thread-Synchronisierung zwischen den beiden Prozessen zu erreichen.

1. Bedingungsvariablen initialisieren.

Statische Initialisierung, pthread_cond_t cond = PTHREAD_COND_INITIALIER;

Dynamische Initialisierung, int pthread_cond_init (pthread_cond_t *cond, pthread_condattr_t *cond_attr);

2. Warten Sie, bis die Bedingungen erfüllt sind. Geben Sie die Sperre frei und blockieren Sie das Warten darauf, dass die Bedingungsvariable wahr ist. timewait() legt die Wartezeit fest, und wenn kein Signal vorhanden ist, kehrt es zu ETIMEOUT zurück (das Sperren stellt sicher, dass nur ein Thread gewartet wird)

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. Bedingungsvariablen aktivieren. pthread_cond_signal, pthread_cond_broadcast (alle wartenden Threads aktivieren)

int pthread_cond_signal (pthread_cond_t *cond);

int pthread_cond_broadcast (pthread_cond_t *cond); //Alle Threads entsperren

4. Löschen Sie die Bedingungsvariable. Kein Thread wartet, sonst EBUSY

int pthread_cond_destroy (pthread_cond_t *cond);
Wie Prozesse können auch Threads über Semaphoren kommunizieren, obwohl sie leichtgewichtig sind. Die Namen der Semaphorfunktionen beginnen alle mit „sem_“. Es gibt vier grundlegende Semaphorfunktionen, die von Threads verwendet werden.

1. Semaphor-Initialisierung.

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

Hiermit wird das durch sem angegebene Semaphor initialisiert und seine Freigabeoption eingerichtet (Linux). unterstützt nur 0, was bedeutet, dass es sich um ein lokales Semaphor des aktuellen Prozesses handelt) und geben Sie ihm dann einen Anfangswert VALUE.

2. Warten Sie auf das Semaphor. Dekrementieren Sie das Semaphor um 1 und warten Sie, bis der Semaphorwert größer als 0 ist.

int sem_wait (sem_t *sem);

3. Erhöhen Sie den Semaphorwert um 1. Und andere wartende Threads benachrichtigen.

int sem_post (sem_t *sem);

4. Zerstöre das Semaphor. Wir bereinigen das Semaphor, nachdem wir es verwendet haben. Gib alle besessenen Ressourcen zurück.

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;
}

Die oben genannten Methoden sind, wie wir alle wissen, das größte Highlight von Threads Es handelt sich um eine gemeinsame Nutzung von Ressourcen, und das Thread-Synchronisationsproblem bei der gemeinsamen Nutzung von Ressourcen stellt eine große Schwierigkeit dar.

Das obige ist der detaillierte Inhalt vonEs gibt verschiedene Methoden zur Thread-Synchronisierung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn