Heim Backend-Entwicklung PHP-Tutorial Linux – Bedingungsvariable (Bedingungsvariable) implementiert das Producer-Consumer-Modell und die Lese-/Schreibsperre

Linux – Bedingungsvariable (Bedingungsvariable) implementiert das Producer-Consumer-Modell und die Lese-/Schreibsperre

Jan 18, 2017 am 10:29 AM

1. Bedingungsvariablen
Während des Thread-Synchronisationsprozesses gibt es auch die folgenden Situationen: Thread A muss warten, bis eine bestimmte Bedingung erfüllt ist, bevor er mit der Ausführung fortfahren kann wird blockiert, während Thread B ausgeführt wird. Wenn diese Bedingung während des Prozesses auftritt, wird Thread A aktiviert, um die Ausführung fortzusetzen. Verwenden Sie Bedingungsvariablen in der Pthread-Bibliothek, um das Warten auf eine Bedingung zu blockieren oder den Thread aufzuwecken, der auf diese Bedingung wartet. Bedingungsvariablen werden durch Variablen vom Typ pthread_cond_t dargestellt.

Verwenden Sie pthread_cond_init, um die Bedingungsvariable zu initialisieren, können Sie auch die Makrodefinition PTHEAD_COND_INITIALIZER verwenden, um sie zu initialisieren, und pthread_cond_destroy verwenden, um die Bedingungsvariable zu zerstören Bei einem Fehler wird eine Fehlernummer zurückgegeben.
Eine Bedingungsvariable wird immer mit einem Mutex verwendet. Ein Thread kann pthread_cond_wait aufrufen, um eine Bedingungsvariable zu blockieren und darauf zu warten:
1. Den Mutex freigeben
3 return
Ein Thread kann pthread_cond_signal aufrufen, um einen anderen Thread aufzuwecken, der auf eine bestimmte Bedingungsvariable wartet, oder er kann pthread_cond_broadcast aufrufen, um alle Threads aufzuwecken, die auf diese Bedingungsvariable warten.
2. Verwenden Sie zur Veranschaulichung das Producer-Consumer-Modell.
Wie der Name schon sagt, müssen Sie zur Implementierung dieses Modells zunächst zwei Rollen haben (Produzent, Konsument). Natürlich muss es eine Gelegenheit geben, beide kritischen Ressourcen zugänglich zu machen (eine Gelegenheit), und die Beziehung zwischen Produzenten und Konsumenten (gegenseitiger Ausschluss) und die Beziehung zwischen Konsumenten (gegenseitiger Ausschluss) müssen verstanden werden, die Beziehung zwischen Produzenten und Konsumenten (Synchronisation und gegenseitiger Ausschluss) ist im Allgemeinen ein Ort, zwei Rollen und drei Beziehungen. Um es mit Code zu implementieren, erzeugt der Produzent ein Datenelement und sendet dann ein Signal zum Konsumieren an den Konsumenten. Nachdem der Konsument es konsumiert hat, sendet er ein Signal an den Produzenten, um den Produzenten anzuweisen, mit der Produktion fortzufahren, und so weiter.

1 #include<stdio.h>  
  2 #include <stdlib.h>  
  3 #include<malloc.h>  
  4 #include<pthread.h>                                                                                                                               
  5 #include<semaphore.h>  
  6 typedef int Data_type;  
  7 typedef int* Data_type_p;  
  8 static pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;//初始化互斥锁  
  9 static pthread_cond_t needProduct=PTHREAD_COND_INITIALIZER;//初始化条件变量  
 10   
 11  
 12 typedef struct listnode //定义一个链表来存放数据(一个场所)  
 13 {  
 14     Data_type data;  
 15     struct listnode* next;  
 16 }list ,*listp,**listpp;  
 17   
 18 listp head=NULL;  
 19   
 20 static listp buyNode(Data_type _data)  
 21 {  
 22     listp tem=(listp)malloc(sizeof(list));  
 23     if(tem)  
 24     {  
 25         tem -> data=_data;  
 26         tem -> next=NULL;  
 27         return tem;  
 28     }  
 29     return NULL;  
 30 }  
 31 void initList(listpp list)  
 32 {  
 33     *list=buyNode(0);  
 34 }  
 35 void push_list(listp list,Data_type _data)  
 36 {  
 37     listp cur=buyNode(_data);  
 38     listp tem=list;  
 39     while(tem->next)  
 40     {  
 41         tem=tem->next;  
 42     }  
 43     tem ->next=cur;  
 44 }  
 45 void deleteList(listp list)  
 46 {  
 47     if(list)  
 48     {  
 49         free(list);  
 50         list=NULL;  
 51     }  
 52 }  
 53 int pop_list(listp list,Data_type_p data)  
 54 {  
 55     if(list ->next==NULL)  
 56     {  
 57         *data =-1;  
 58         return -1;  
 59     }  
 60     listp tem=list->next;  
 61     list ->next=tem->next;  
 62     *data=tem->data;  
 63     deleteList(tem);  
 64     return 0;  
 65 }  
 66 void PrintList(listp list)  
 67 {  
 68     listp cur=list->next;;  
 69     while(cur)  
 70     {  
 71         printf("%d",cur->data);  
 72         fflush(stdout);  
 73         cur=cur->next;  
 74     }  
 75     printf("\n");  
 76 }  
 77 void *product(void* arg)//定义生产者与生产者之间的关系(互斥)  
 78 {  
 79     int i=0;  
 80     while(1)  
 81     {  
 82         pthread_mutex_lock(&lock);  
 83         printf("product data:%d\n",i);  
 84         push_list(head,i++);  
 85         pthread_mutex_unlock(&lock);  
 86         printf("conduct is ok.weak up comsumer...\n");  
 87         pthread_cond_signal(&needProduct);//当生产者有数据时,发送信号,唤醒消费者  
 88         sleep(2);  
 89     }  
 90   
 91 }  
 92 void *consumer(void* arg)//消费者与消费者之间的关系(互斥)  
 93 {  
 94     Data_type _data;  
 95     while(1)  
 96     {     
 97         pthread_mutex_lock(&lock);  
 98         while(-1==pop_list(head,&_data))  
 99         {  
100             pthread_cond_wait(&needProduct,&lock);//没收到生产者的消息之前就阻塞等待  
101         }  
102         printf("consumer data:%d\n",_data);  
103         pthread_mutex_unlock(&lock);  
104         sleep(1);  
105     }  
106 }  
107 int main()  
108 {  
109     initList(&head);  
110     pthread_t id1;  
111     pthread_t id2;  
112     pthread_create(&id1,NULL,product,NULL);  
113     pthread_create(&id2,NULL,consumer,NULL);  
114     pthread_join(id1,NULL);  
115     pthread_join(id2,NULL);  
116     return 0;  
117 }
Nach dem Login kopieren
Zusammenfassung: Der obige Code implementiert einen einzelnen Produzenten und einen einzelnen Konsumenten, das Produzent-Konsumenten-Modell. Einfach ausgedrückt dient er dazu, eine sich gegenseitig ausschließende Beziehung zwischen Produzenten und Konsumenten zu erreichen. und eine synchronisierte, sich gegenseitig ausschließende Beziehung zwischen Produzenten und Verbrauchern.


3. Verwenden Sie Semaphor, um das Producer-Consumer-Modell zu implementieren.
Die Mutex-Variable ist entweder 0 oder 1, was als verfügbare Menge einer Ressource angesehen werden kann. Bei der Initialisierung ist Mutex 1, was darauf hinweist, dass dies der Fall ist eine verfügbare Ressource. ,
Erhalten Sie die Ressource beim Sperren, reduzieren Sie Mutex auf 0, um anzuzeigen, dass keine weitere verfügbare Ressource vorhanden ist, geben Sie die Ressource beim Entsperren frei und erhöhen Sie Mutex wieder auf 1, um anzuzeigen, dass eine weitere verfügbare Ressource vorhanden ist. Semaphor ähnelt Mutex und stellt die Anzahl der verfügbaren Ressourcen dar. Im Gegensatz zu Mutex kann diese Zahl größer als 1 sein. Das heißt, wenn die Anzahl der durch das Semaphor beschriebenen Ressourcen 1 beträgt, sind das Semaphor und die Mutex-Sperre zu diesem Zeitpunkt gleich!
sem_init() initialisiert das Semaphor

sem_wait()P-Operation erhält Ressourcen

sem_post()V-Operation gibt Ressourcen frei

sem_destroy() zerstört das Semaphor

Das Obige ist ein in einer verknüpften Liste geschriebenes Producer-Consumer-Modell, dessen Speicherplatz dynamisch zugewiesen wird. Jetzt wird das Producer-Consumer-Modell basierend auf einer Ringwarteschlange mit fester Größe neu geschrieben

1 #include<stdio.h>  
  2 #include<pthread.h>  
  3 #include<semaphore.h>  
  4 #define PRODUCT_SIZE 20  
  5 #define CONSUMER_SIZE 0  
  6   
  7 sem_t produceSem;  
  8 sem_t consumerSem;  
  9 int Blank [PRODUCT_SIZE];  
 10   
 11 void* product(void* arg)  
 12 {  
 13     int p=0;  
 14     while(1)  
 15     {  
 16         sem_wait(&produceSem); //申请资源。  
 17         int _product=rand()%100;  
 18         Blank[p]=_product;  
 19         printf("product is ok ,value is :%d\n",_product);  
 20         sem_post(&consumerSem);//释放资源  
 21         p=(p+1) % PRODUCT_SIZE;  
 22         sleep(rand()%3);  
 23     }  
 24   
 25 }  
 26 void* consumer(void* arg)  
 27 {  
 28     int p=0;  
 29     while(1)  
 30     {  
 31         sem_wait(&consumerSem);//申请资源  
 32         int _consumer=Blank[p];  
 33         printf("consumer is ok,value is :%d\n",_consumer);  
 34         sem_post(&produceSem);//释放资源  
 35         p=(p+1)% PRODUCT_SIZE;  
 36         sleep(rand()%5);  
 37     }  
 38 }  
 39 int main()  
 40 {   sem_init(&produceSem,0,PRODUCT_SIZE);  
 41     sem_init(&consumerSem,0,CONSUMER_SIZE);  
 42     pthread_t tid1,tid2;  
 43     pthread_create(&tid1,NULL,product,NULL);  
 44     pthread_create(&tid2,NULL,consumer,NULL);  
 45     pthread_join(tid1,NULL);  
 46     pthread_join(tid2,NULL);  
 47     sem_destroy(&produceSem);  
 48     sem_destroy(&consumerSem);  
 49     return 0;  
 50 }
Nach dem Login kopieren
4 . Die Lese-/Schreibsperre ist eigentlich eine spezielle Spin-Sperre, die verwendet wird, um die Situation zu bewältigen, in der mehr Leser und Autoren nur auf gemeinsam genutzte Ressourcen zugreifen , müssen Autoren auf gemeinsam genutzte Ressourcen schreiben. Diese Art von Sperre kann die Parallelität im Vergleich zu Spin-Sperren verbessern, da sie in einem Multiprozessorsystem mehreren Lesern den gleichzeitigen Zugriff auf gemeinsam genutzte Ressourcen ermöglicht und die maximal mögliche Anzahl von Lesern der tatsächlichen Anzahl logischer CPUs entspricht. Schreiber sind exklusiv. Eine Lese-/Schreibsperre kann nur einen Schreiber oder mehrere Leser gleichzeitig haben (abhängig von der Anzahl der CPUs), sie kann jedoch nicht gleichzeitig Lese- und Schreiber haben. Lese-/Schreibsperren folgen ebenfalls drei Beziehungen: Leser-Schreiber (sich gegenseitig ausschließend und synchronisiert), Leser-Leser (keine Beziehung), Schriftsteller-Schreiber (sich gegenseitig ausschließend), 2 Objekte (Leser und Schreiber), 1 Standort.

pthread_rwlock_wrlock-Schreibmodus, gibt 0 bei Erfolg zurück, Fehlercode bei Fehler

pthread_rwlock_rdlock-Lesemodus, gibt 0 bei Erfolg und Fehlercode bei Fehler zurück

pthread_rwlock_init-Initialisierung

Das Obige ist der Inhalt der Linux-Bedingungsvariablen (Bedingungsvariable) zur Implementierung des Producer-Consumer-Modells und der Lese-/Schreibsperre. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn). )!
1 #include<stdio.h>  
  2 #include<pthread.h>  
  3 #define _READNUM_ 2  
  4 #define _WREITENUM_ 3  
  5 pthread_rwlock_t lock;  
  6 int buf=0;  
  7 void* read(void* reg)  
  8 {  
  9     while(1)  
 10     {  
 11         if(pthread_rwlock_tryrdlock(&lock) != 0)//读方式  
 12         {  
 13             printf("writer is write! reader wait...\n");  
 14         }  
 15         else  
 16         {  
 17             printf("reader is reading,val is %d\n",buf);  
 18             pthread_rwlock_unlock(&lock);  
 19         }  
 20         sleep(2);  
 21     }  
 22 }  
 23 void* write(void* reg)  
 24 {  
 25     while(1)  
 26     {  
 27         if(pthread_rwlock_trywrlock(&lock) != 0)//写方式  
 28         {  
 29             printf("reader is reading ! writer wait...\n");  
 30             sleep(1);  
 31         }  
 32         else  
 33         {  
 34             buf++;  
 35             printf("writer is writing,val is %d\n",buf);  
 36             pthread_rwlock_unlock(&lock);  
 37   
 38         }  
 39         sleep(1);  
 40     }  
 41 }  
 42 int main()  
 43 {  
 44     pthread_rwlock_init(&lock,NULL);  
 45     pthread_t tid;  
 46     int i=0;  
 47     for(i;i< _WREITENUM_;i++)  
 48     {  
 49         pthread_create(&tid,NULL,write,NULL);  
 50     }  
 51   
 52     for(i; i< _READNUM_;i++)  
 53     {  
 54         pthread_create(&tid,NULL,read,NULL);  
 55     }  
 56         pthread_join(tid,NULL);  
 57         sleep(100);  
 58         return 0;  
 59 }
Nach dem Login kopieren

Erklärung dieser Website
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

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Deepseek Web Version Eingang Deepseek Offizielle Website Eingang Deepseek Web Version Eingang Deepseek Offizielle Website Eingang Feb 19, 2025 pm 04:54 PM

Deepseek ist ein leistungsstarkes Intelligent -Such- und Analyse -Tool, das zwei Zugriffsmethoden bietet: Webversion und offizielle Website. Die Webversion ist bequem und effizient und kann ohne Installation verwendet werden. Unabhängig davon, ob Einzelpersonen oder Unternehmensnutzer, können sie massive Daten über Deepseek problemlos erhalten und analysieren, um die Arbeitseffizienz zu verbessern, die Entscheidungsfindung zu unterstützen und Innovationen zu fördern.

So installieren Sie Deepseek So installieren Sie Deepseek Feb 19, 2025 pm 05:48 PM

Es gibt viele Möglichkeiten, Deepseek zu installieren, einschließlich: kompilieren Sie von Quelle (für erfahrene Entwickler) mit vorberechtigten Paketen (für Windows -Benutzer) mit Docker -Containern (für bequem am besten, um die Kompatibilität nicht zu sorgen), unabhängig von der Methode, die Sie auswählen, bitte lesen Die offiziellen Dokumente vorbereiten sie sorgfältig und bereiten sie voll und ganz vor, um unnötige Schwierigkeiten zu vermeiden.

Wie löste ich das Problem der Berechtigungen beim Betrachten der Python -Version in Linux Terminal? Wie löste ich das Problem der Berechtigungen beim Betrachten der Python -Version in Linux Terminal? Apr 01, 2025 pm 05:09 PM

Lösung für Erlaubnisprobleme beim Betrachten der Python -Version in Linux Terminal Wenn Sie versuchen, die Python -Version in Linux Terminal anzuzeigen, geben Sie Python ein ...

Bitget Offizielle Website -Installation (2025 Anfängerhandbuch) Bitget Offizielle Website -Installation (2025 Anfängerhandbuch) Feb 21, 2025 pm 08:42 PM

Bitget ist eine Kryptowährungsbörse, die eine Vielzahl von Handelsdienstleistungen anbietet, darunter Spot -Handel, Vertragshandel und Derivate. Der 2018 gegründete Austausch hat seinen Hauptsitz in Singapur und verpflichtet sich, den Benutzern eine sichere und zuverlässige Handelsplattform zu bieten. Bitget bietet eine Vielzahl von Handelspaaren, einschließlich BTC/USDT, ETH/USDT und XRP/USDT. Darüber hinaus hat der Austausch einen Ruf für Sicherheit und Liquidität und bietet eine Vielzahl von Funktionen wie Premium -Bestellarten, gehebelter Handel und Kundenunterstützung rund um die Uhr.

Holen Sie sich das Installationspaket Gate.io kostenlos Holen Sie sich das Installationspaket Gate.io kostenlos Feb 21, 2025 pm 08:21 PM

Gate.io ist ein beliebter Kryptowährungsaustausch, den Benutzer verwenden können, indem sie sein Installationspaket herunterladen und auf ihren Geräten installieren. Die Schritte zum Abholen des Installationspakets sind wie folgt: Besuchen Sie die offizielle Website von Gate.io, klicken Sie auf "Download", wählen Sie das entsprechende Betriebssystem (Windows, Mac oder Linux) und laden Sie das Installationspaket auf Ihren Computer herunter. Es wird empfohlen, die Antiviren -Software oder -Firewall während der Installation vorübergehend zu deaktivieren, um eine reibungslose Installation zu gewährleisten. Nach Abschluss muss der Benutzer ein Gate.io -Konto erstellen, um es zu verwenden.

Ouyi OKX Installationspaket ist direkt enthalten Ouyi OKX Installationspaket ist direkt enthalten Feb 21, 2025 pm 08:00 PM

Ouyi Okx, die weltweit führende digitale Asset Exchange, hat jetzt ein offizielles Installationspaket gestartet, um ein sicheres und bequemes Handelserlebnis zu bieten. Auf das OKX -Installationspaket von Ouyi muss nicht über einen Browser zugegriffen werden. Der Installationsprozess ist einfach und einfach zu verstehen.

Wie setze ich nach dem Neustart des Systems automatisch Berechtigungen von Unixsocket fest? Wie setze ich nach dem Neustart des Systems automatisch Berechtigungen von Unixsocket fest? Mar 31, 2025 pm 11:54 PM

So setzen Sie die Berechtigungen von Unixsocket automatisch nach dem Neustart des Systems. Jedes Mal, wenn das System neu startet, müssen wir den folgenden Befehl ausführen, um die Berechtigungen von Unixsocket: sudo ...

Ouyi Exchange Download Official Portal Ouyi Exchange Download Official Portal Feb 21, 2025 pm 07:51 PM

Ouyi, auch bekannt als OKX, ist eine weltweit führende Kryptowährungsplattform. Der Artikel enthält ein Download -Portal für das offizielle Installationspaket von Ouyi, mit dem Benutzer den Ouyi -Client auf verschiedenen Geräten installiert werden können. Dieses Installationspaket unterstützt Windows, Mac, Android und iOS -Systeme. Nach Abschluss der Installation können sich Benutzer registrieren oder sich beim Ouyi -Konto anmelden, Kryptowährungen mit dem Handel mit den von der Plattform erbrachten Diensten anmelden.

See all articles