logo

MULTITHREADING IN C

Einführung:

In C der Begriff „Multithreading“ beschreibt die Verwendung zahlreicher Threads gleichzeitig. Jeder Thread führt eine aus andere Aufgabe . Aufgrund der gleichzeitigen Natur des Multithreadings können viele Aufgaben gleichzeitig ausgeführt werden. Zusätzlich, Multithreading reduziert die Ressourcennutzung der CPU . Es gibt zwei Kategorien von Multitasking: prozessbasiert Und threadbasiert . Wenn etwas als Multithreading bezeichnet wird, bedeutet dies, dass mindestens zwei oder möglicherweise mehr Threads gleichzeitig im selben Prozess ausgeführt werden. Um Multithreading in C zu verstehen, müssen wir zunächst verstehen, was ein Thread und ein Prozess sind. Schauen wir uns diese Themen an, um ein besseres Verständnis zu erlangen.

Name von

Was sind Prozesse und Threads?

A Faden ist der grundlegendes Gebäude Block der Ausführung eines Prozesses. Ein Programm besteht aus mehreren Prozessen und jeder Prozess besteht aus Threads, die viel grundlegendere Einheiten sind. Daher kann der Thread als grundlegender Baustein eines Prozesses oder als einfachere Einheit betrachtet werden, die gemeinsam die CPU-Auslastung bestimmt.

Die folgenden Elemente sind in einem Thread enthalten:

Thread-ID:

Es ist etwas Besonderes Thread-ID Dies wird zum Zeitpunkt der Thread-Bildung generiert und für die Dauer dieses bestimmten Threads beibehalten.

Programm zähler:

Es ist ein Wert, den die Hardwarelasten .

Ein registrierter Satz:

Es ist eine Sammlung von gemeinsame Register .

Ein Stapel:

Es ist ein Überbleibsel davon bestimmten Thread .

Wenn außerdem zwei Threads gleichzeitig im selben Prozess arbeiten, teilen sie sich diese Code , Datenabschnitte , und andere Betriebssystemressourcen wie Datei öffnet Und Signale . Ein schwerer Prozess, eine Art herkömmlicher Prozess, kann einen Thread steuern. Ein Multithread der Steuerung kann jedoch mehrere Aufgaben gleichzeitig öffnen und ausführen. Durch den Einsatz von Threads wird das System wesentlich effektiver, weshalb diese sinnvoll sind.

Der Unterschied zwischen einzel Und Multithreading in C wird erklärt. Zunächst einmal ist es ein Single-Threaded-Prozess . Dadurch wird der gesamte Block inklusive der Code, Daten, usw. – wird als ein Prozess betrachtet, und dieser Prozess hat nur einen Thread. Dies bedeutet, dass diese Technik jeweils nur eine Aufgabe erledigt. Aber es gibt eine Multithreading-Prozess das steht im Widerspruch dazu. Es gibt Aktivitäten wie Code, Stapel, Daten , Und Dateien auch, aber sie werden von mehreren Threads ausgeführt, von denen jeder seinen eigenen Stapel und seine eigenen Register hat. Da in dieser Situation zahlreiche Aufgaben gleichzeitig erledigt werden können, wird der Vorgang als a bezeichnet Multithreading-Prozess .

Garn gibt es in zwei Varianten:

Thread auf Benutzerebene:

Es handelt sich, wie der Name schon vermuten lässt, um eine Benutzerebene. Der Kernel erhält keinen Zugriff auf seine Daten.

img CSS ausrichten

Thread auf Kernel-Ebene

Die Art des Threads bezieht sich auf die Beziehung des Threads zum Kernel und zum Betriebssystem des Systems.

Verfahren- Die Reihe von Schritten zur Ausführung eines Programms kann als bezeichnet werden Verfahren . Ein Programm wird nicht sofort ausgeführt, wenn es ausgeführt wird. Es ist in einige grundlegende Schritte unterteilt, die nacheinander und auf organisierte Weise ausgeführt werden, um schließlich zur Ausführung eines Prozesses zu führen.

Ein Prozess, der in kleinere Schritte zerlegt wurde, wird als a bezeichnet 'Klon oder untergeordneter Prozess', während der ursprüngliche Prozess als bezeichnet wird „übergeordneter“ Prozess . Im Speicher belegt jeder Prozess eine bestimmte Menge an Speicherplatz, der nicht mit anderen Prozessen geteilt wird.

Ein Verfahren durchläuft vor der Ausführung einige Phasen.

NEU-

In dieser Situation ist ein neuer Prozess generiert .

BEREIT-

Wenn ein Prozess vorbereitet ist und auf die Zuweisung eines Prozessors wartet, befindet er sich in diesem Zustand.

LÄUFT-

Wenn der Prozess aktiv ist, ist es der Zustand.

WARTEN-

Wenn sich ein Prozess in diesem Zustand befindet, ist etwas vorhanden warten passieren.

BEENDET-

Es handelt sich um den Staat, in dem das Verfahren durchgeführt wird.

Warum ist C Multithreading?

Multithreading in der C-Idee kann durch Parallelität genutzt werden, um eine zu verbessern Funktionalität der Anwendung . Stellen Sie sich den Fall vor, dass in einem Browserfenster mehrere Registerkarten geöffnet sind. Dann funktioniert jede Registerkarte gleichzeitig und wird möglicherweise als a bezeichnet Faden . Vorausgesetzt, wir verwenden Microsoft Excel , ein Thread wird es schaffen Textformatierung , und ein Thread wird es tun Behandeln Sie die Eingabe . Daher erleichtert die Multithreading-Funktion von C die gleichzeitige Ausführung mehrerer Aufgaben. Das Erstellen eines Threads geht deutlich schneller. Die Kontextübertragung über Threads hinweg erfolgt schneller. Darüber hinaus kann die Kommunikation zwischen Threads schneller erfolgen und die Thread-Beendigung ist einfacher.

Wie schreibe ich C-Programme für Multithreading?

Obwohl Multithreading-Anwendungen nicht in die C-Sprache integriert sind, ist dies je nach Betriebssystem möglich. Der threads.h Standardbibliothek wird verwendet, um die Multithreading-Idee in umzusetzen C . Derzeit gibt es jedoch keinen Compiler, der dies kann. Wir müssen plattformspezifische Implementierungen verwenden, wie z 'POSIX' Threads-Bibliothek mithilfe der Header-Datei pthread.h , wenn wir Multithreading in C verwenden wollen. 'Pthreads' ist ein anderer Name dafür. A POSIX Threads können auf folgende Weise erstellt werden:

 #include pthread_create (thread, attr, start_routine, arg) 

In diesem Fall, Pthread_create Erstellt einen neuen Thread, um den Thread ausführbar zu machen. Damit können Sie Multithreading in C beliebig oft in Ihrem Code implementieren. Die Parameter und ihre Beschreibungen von früher sind hier aufgelistet.

Escape-Zeichen Java

Faden:

es ist ein einzigartige Identifikation dass die Unterprozess kehrt zurück .

attr:

Wenn wir Thread-Attribute festlegen möchten, verwenden wir dies undurchsichtiges Attribut .

start_routine:

Wann start_routine generiert wird, führt der Thread eine Routine aus.

arg:

Der Parameter, den die start_routine erhält. NULL wird verwendet, wenn keine Argumente angegeben werden.

Bestimmte C-Multithreading-Beispiele

Hier sind einige Beispiele für Multithreading-Probleme in C.

1. Das Reader-Writer-Problem

Ein häufiges Betriebssystemproblem bei der Prozesssynchronisierung ist das Lese-/Schreibproblem . Angenommen, wir haben eine Datenbank Leser Und Schriftsteller , zwei verschiedene Benutzerkategorien, können darauf zugreifen. Leser sind die einzigen, die es können lesen die Datenbank, wohingegen Schriftsteller sind die einzigen, die die Datenbank lesen und auch aktualisieren können. Lasst uns verwenden IRCTC als einfaches Beispiel. Wenn wir den Status einer bestimmten Person überprüfen möchten Zugnummer Geben Sie einfach die Zugnummer in das System ein, um die entsprechenden Zuginformationen anzuzeigen. Hier werden nur die Informationen angezeigt, die auf der Website vorhanden sind. Der Leseoperator ist dieser. Wenn wir jedoch ein Ticket reservieren möchten, müssen wir das Ticketbuchungsformular mit Angaben wie unserem Namen, Alter usw. ausfüllen. Daher führen wir hier einen Schreibvorgang durch. Es werden einige Anpassungen vorgenommen IRCTC-Datenbank .

Das Problem besteht darin, dass mehrere Personen gleichzeitig versuchen, auf das zuzugreifen IRCTC-Datenbank . Sie könnten ein sein Schriftsteller oder ein Leser . Das Problem entsteht, wenn ein Leser die Datenbank bereits nutzt und ein Autor gleichzeitig darauf zugreift, um an denselben Daten zu arbeiten. Ein weiteres Problem entsteht, wenn ein Autor eine Datenbank verwendet und ein Leser auf dieselben Informationen wie in der Datenbank zugreift. Drittens entsteht eine Schwierigkeit, wenn ein Autor die Datenbank aktualisiert, während ein anderer versucht, Daten in derselben Datenbank zu aktualisieren. Das vierte Szenario tritt auf, wenn zwei Leser versuchen, dasselbe Material abzurufen. All diese Probleme treten auf, wenn der Leser und der Autor dieselben Datenbankdaten verwenden.

Semaphore ist eine Methode, die zur Lösung dieses Problems eingesetzt wird. Schauen wir uns eine Veranschaulichung an, wie dieses Problem verwendet werden kann.

Leserprozess:

 #include #include #include int rc = 0; // Reader count int data = 0; // Shared data pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_twrt = PTHREAD_COND_INITIALIZER; void* reader(void* arg) { int reader_id = *(int*)arg; pthread_mutex_lock(&mutex); rc++; if (rc == 1) pthread_cond_wait(&wrt, &mutex); pthread_mutex_unlock(&mutex); // Reading the shared data printf('Reader %d reads data: %d
&apos;, reader_id, data); pthread_mutex_lock(&amp;mutex); rc--; if (rc == 0) pthread_cond_signal(&amp;wrt); pthread_mutex_unlock(&amp;mutex); return NULL; } int main() { pthread_treaders[5]; // Assuming 5 reader threads int reader_ids[5]; for (int i = 0; i<5; i++) { reader_ids[i]="i" + 1; pthread_create(&readers[i], null, reader, &reader_ids[i]); } joining reader threads for (int i="0;" i< 5; pthread_join(readers[i], null); return 0; < pre> <p> <strong>Output:</strong> </p> <pre> Reader 1 reads data: 0 Reader 2 reads data: 0 Reader 3 reads data: 0 Reader 4 reads data: 0 Reader 5 reads data: 0 </pre> <p> <strong>Explanation:</strong> </p> <p>In this code, we have the shared variable data and the <strong> <em>reader count rc</em> </strong> . The <strong> <em>wrt condition</em> </strong> variable is used to limit access for the <strong> <em>writer process</em> </strong> , and the <strong> <em>mutex</em> </strong> is used to guarantee mutual exclusion for accessing the shared data.</p> <p>The reader process is represented by the <strong> <em>reader() function</em> </strong> . The <strong> <em>reader count (rc)</em> </strong> is increased before attaining the <strong> <em>mutex lock</em> </strong> . It uses <strong> <em>pthread_cond_wait()</em> </strong> to wait on the <strong> <em>wrt condition</em> </strong> variable if it is the <strong> <em>first reader (rc == 1)</em> </strong> . As a result, writers will be prevented from writing until all readers have completed.</p> <p>The reader process checks if it was the <strong> <em>last reader (rc == 0)</em> </strong> and lowers the reader <strong> <em>count (rc--)</em> </strong> after reading the shared data. If it was, <strong> <em>pthread_cond_signal()</em> </strong> signals the <strong> <em>wrt condition</em> </strong> variable to let waiting writer processes continue.</p> <p>Using the <strong> <em>pthread_create()</em> </strong> and <strong> <em>pthread_join() functions</em> </strong> , we <strong> <em>new</em> </strong> and <strong> <em>join</em> </strong> multiple reader threads in the <strong> <em>main() function</em> </strong> . An individual ID is assigned to each reader thread for identifying purposes.</p> <h3>Writer process:</h3> <pre> wait(wrt); . . WRITE INTO THE OBJECT . signal(wrt); </pre> <p>In the above example, same as the <strong> <em>reader process</em> </strong> , an operation known as the wait operation is carried out on <strong> <em>&apos;wrt&apos;</em> </strong> when a user wishes to access the data or object. After that, the new user won&apos;t be able to access the object. And once the user has finished writing, another signal operation is performed on <strong> <em>wrt</em> </strong> .</p> <h3>2. lock and unlock problem:</h3> <p>The idea of a <strong> <em>mutex</em> </strong> is utilized in multithreading in C to guarantee that there won&apos;t be a <strong> <em>race condition</em> </strong> between the <strong> <em>threads</em> </strong> . When multiple threads begin processing the same data at once, this circumstance is known as <strong> <em>racing</em> </strong> . However, if these circumstances exist, we must. We use the <strong> <em>mutex&apos;s lock()</em> </strong> and <strong> <em>unlock() functions</em> </strong> to secure a particular section of code for a specific thread. Such that, another thread cannot begin performing the same operation. The <strong> <em>&apos;critical section/region&apos;</em> </strong> is the name given to this protected code area. Before using the shared resources, we set up a lot in a certain area, and once we&apos;ve finished using them, we unlock them once more.</p> <p>Let&apos;s examine the operation of the mutex for locking and unlocking in multithreading in C:</p> <p> <strong>Example:</strong> </p> <pre> #include #include #include pthread_mutex_tmy_mutex = PTHREAD_MUTEX_INITIALIZER; int shared_data = 0; void *thread_function(void *arg) { pthread_mutex_lock(&amp;my_mutex); shared_data++; // Modify the shared data printf(&apos;Thread %ld: Shared data modified. New value: %d
&apos;, (long)arg, shared_data); pthread_mutex_unlock(&amp;my_mutex); return NULL; } int main() { pthread_tthreads[5]; // Assuming 5 threads for (int i = 0; i<5; i++) { if (pthread_create(&threads[i], null, thread_function, (void *)(long)(i + 1)) !="0)" fprintf(stderr, 'error creating thread %d
', i 1); return 1; } for (int i< 5; (pthread_join(threads[i], null) joining 0; < pre> <p> <strong>Output:</strong> </p> <pre> Thread 1: Shared data modified. New value: 1 Thread 2: Shared data modified. New value: 2 Thread 3: Shared data modified. New value: 3 Thread 4: Shared data modified. New value: 4 Thread 5: Shared data modified. New value: 5 </pre> <p> <strong>Explanation:</strong> </p> <p>In this above example, we explain how we <strong> <em>lock</em> </strong> and <strong> <em>unlock</em> </strong> a certain region of code that shields us from the racing situation. <strong> <em>&apos;pthread_mutex_t&apos;</em> </strong> is used as an <strong> <em>initializer</em> </strong> in the example above. <strong> <em>&apos;pthread_mutex_lock&apos;</em> </strong> is then <strong> <em>written</em> </strong> before the beginning of the code that we want to lock. The coding that we wish to lock is finished after that. After that, the locking of the code is terminated using <strong> <em>&apos;pthread_mutex_unlock&apos;</em> </strong> ; going forward, no code will be in lock mode.</p> <h2>The Dining Philosopher Problem:</h2> <p>One of the classic issues with synchronization is the <strong> <em>dining philosopher issue</em> </strong> . Simple resource allocation for several processes is required but shouldn&apos;t result in a <strong> <em>stalemate</em> </strong> or <strong> <em>hunger</em> </strong> . The <strong> <em>dining philosopher problem</em> </strong> can be viewed as a straightforward representation of a number of processes, each of which is demanding resources. Since each of these processes requires a resource allocation, it is necessary to distribute those resources across all of the processes so that no one process ever gets stuck or stops working.</p> <p>Assume there are five philosophers seated at a <strong> <em>circle-shaped table</em> </strong> . They eat at one point and ponder about something at another. Around the round table, the philosophers are evenly spaced out on the chairs. Additionally, there is a bowl of rice and five chopsticks for each philosopher in the middle of the table. When the philosopher feels she cannot interact with her colleagues who are seated nearby.</p> <p>A philosopher occasionally takes up two chopsticks when she becomes hungry. She chooses two chopsticks from her neighbors-one on her <strong> <em>left</em> </strong> and one on her <strong> <em>right</em> </strong> -that are within easy reach. But the philosopher should never pick up more than one chopstick at once. She will obviously be unable to pick up the chopstick that the neighbor is using.</p> <p> <strong>Example:</strong> </p> <p>Let&apos;s use an example to demonstrate how this is implemented in C.</p> <pre> #include #include #include #include #include pthread_tphilosopher[5]; pthread_mutex_tchopstick[5]; void *func(void *arg) { int n = *(int *)arg; printf(&apos;
Philosopher %d is thinking.&apos;, n); pthread_mutex_lock(&amp;chopstick[n]); pthread_mutex_lock(&amp;chopstick[(n + 1) % 5]); printf(&apos;
Philosopher %d is eating.&apos;, n); sleep(3); pthread_mutex_unlock(&amp;chopstick[n]); pthread_mutex_unlock(&amp;chopstick[(n + 1) % 5]); printf(&apos;
Philosopher %d Finished eating &apos;, n); return NULL; } int main() { int i, k; void *message; for (i = 0; i<5; i++) { k="pthread_mutex_init(&amp;chopstick[i]," null); if (k !="0)" printf('failed to initialize the mutex
'); exit(1); } for (i="0;" i< 5; null, func, (void *)&i); printf('error in thread creation.
'); &message); join thread.
'); printf('mutex destroyed.
'); return 0; < pre> <p> <strong>Output:</strong> </p> <pre> Philosopher 0 is thinking. Philosopher 1 is thinking. Philosopher 2 is thinking. Philosopher 3 is thinking. Philosopher 4 is thinking. Philosopher 0 is eating. Philosopher 1 is eating. Philosopher 2 is eating. Philosopher 3 is eating. Philosopher 4 is eating. Philosopher 0 Finished eating Philosopher 1 Finished eating Philosopher 2 Finished eating Philosopher 3 Finished eating Philosopher 4 Finished eating </pre> <p> <strong>Explanation:</strong> </p> <p> <strong> <em>Chopsticks</em> </strong> can be represented by a semaphore. Since there are <strong> <em>chopsticks</em> </strong> on the table and no philosopher has chosen one, all of the chopsticks&apos; components are first initialized to <strong> <em>1</em> </strong> . Now that <strong> <em>chopstick[i]</em> </strong> has been chosen as the first <strong> <em>chopstick. chopstick[i]</em> </strong> and <strong> <em>chopstick[(i+1)%5]</em> </strong> are subject to the first wait operation. These <strong> <em>chopsticks&apos; wait operation</em> </strong> indicates that the philosopher has picked them up. The eating process begins once the philosopher selects his <strong> <em>chopstick</em> </strong> . The signal operation is now carried out on the <strong> <em>chopsticks [i]</em> </strong> and <strong> <em>[(i+1)%5]</em> </strong> once the philosopher has finished eating. The philosopher then turns back to sleep.</p> <p>To determine whether the <strong> <em>subthread</em> </strong> has joined the main thread or not, we used the <strong> <em>pthread_join function</em> </strong> . Similarly, we have checked whether the <strong> <em>mutex</em> </strong> lock has been initialized using the <strong> <em>pthread_mutex_init</em> </strong> method.</p> <p>To initialize and verify whether the new thread was created or not, we utilized the <strong> <em>pthread_create function</em> </strong> . Similar to this, we destroyed the <strong> <em>mutex lock</em> </strong> using the <strong> <em>pthread_mutex_destroy</em> </strong> function.</p> <h2>The Producer-Consumer Problem:</h2> <p>A common issue with multithreading process synchronization is the <strong> <em>producer-consumer problem</em> </strong> . Two processes are present in it: the first is the <strong> <em>producer&apos;s process</em> </strong> , and the second is the <strong> <em>consumer&apos;s process</em> </strong> . Furthermore, it is assumed that both operations are occurring concurrently in parallel. Additionally, they are a cooperative process, which implies that they are sharing something with one another. It is important that when the buffer is <strong> <em>full</em> </strong> , the producer cannot add data. When the buffer is empty, the consumer cannot extract data from the buffer because the common buffer size between the producer and the consumer is <strong> <em>fixed</em> </strong> . The issue is stated in this way. Hence, to implement the Producer-Consumer problem and solve it, we shall employ the idea of parallel programming.</p> <p> <strong>Example:</strong> </p> <pre> #include #include int mutex = 1, full = 0, empty = 3, x = 0; int main() { int n; void producer(); void consumer(); int wait(int); int signal(int); printf(&apos;
1.producer
2.consumer
3.for exit&apos;); while (1) { printf(&apos;
 Please enter your choice:&apos;); scanf(&apos;%d&apos;, &amp;n); switch (n) { case 1: if ((mutex == 1) &amp;&amp; (empty != 0)) producer(); else printf(&apos;Oops!! the buffer is full!!&apos;); break; case 2: if ((mutex == 1) &amp;&amp; (full != 0)) consumer(); else printf(&apos;Oops!! the buffer is empty!!&apos;); break; case 3: exit(0); break; } } return 0; } int wait(int s) { return (--s); } int signal(int s) { return (++s); } void producer() { mutex = wait(mutex); full = signal(full); empty = wait(empty); x++; printf(&apos;
Item produced by the Producer %d&apos;, x); mutex = signal(mutex); } void consumer() { mutex = wait(mutex); full = wait(full); empty = signal(empty); printf(&apos;
Item consumed by the Consumer %d&apos;, x); x--; mutex = signal(mutex); } </pre> <p> <strong>Output:</strong> </p> <pre> 1. producer 2. consumer 3. for exit Please enter your choice: </pre> <p> <strong>Explanation:</strong> </p> <p>We perform two tasks. The functions <strong> <em>consumer()</em> </strong> and <strong> <em>producer()</em> </strong> indicate the status and operation of the <strong> <em>consumer</em> </strong> and <strong> <em>producer</em> </strong> . The <strong> <em>producer() method</em> </strong> will create the <strong> <em>mutex lock</em> </strong> and determine whether the buffer is <strong> <em>full</em> </strong> when it is called. When the buffer is full, nothing will be produced. If not, it will <strong> <em>create</em> </strong> , and then, after the <strong> <em>production</em> </strong> , it will put itself to sleep to unlock the <strong> <em>mutex lock</em> </strong> . Like the <strong> <em>producer</em> </strong> , the consumer first creates the <strong> <em>mutex lock</em> </strong> , checks the <strong> <em>buffer</em> </strong> , consumes the <strong> <em>product</em> </strong> , and then releases the lock before going back to sleep.</p> <p>A <strong> <em>counter (x)</em> </strong> will be used during manufacturing and will keep growing until the manufacturer produces the item. However, the consumer will make fewer of the same manufactured <strong> <em>item (x)</em> </strong> .</p> <h2>Conclusion:</h2> <p>The idea of using <strong> <em>two</em> </strong> or <strong> <em>more threads</em> </strong> to execute a program is known as <strong> <em>multithreading</em> </strong> in the C programming language. <strong> <em>Multithreading</em> </strong> allows for the simultaneous execution of several tasks. The simplest executable component of a program is a <strong> <em>thread</em> </strong> . The process is the idea that a task can be completed by breaking it up into several smaller <strong> <em>sub-processes</em> </strong> .</p> <p>The header file <strong> <em>pthread.h</em> </strong> is required in order to implement multithreading in C since it cannot be done directly.</p> <hr></5;></pre></5;></pre></5;>

Erläuterung:

In diesem Code haben wir die gemeinsam genutzten Variablendaten und die Leseranzahl rc . Der bzgl. Zustand Variable wird verwendet, um den Zugriff für zu beschränken Schreibprozess , und das Mutex wird verwendet, um einen gegenseitigen Ausschluss für den Zugriff auf die gemeinsam genutzten Daten zu gewährleisten.

Der Leserprozess wird durch die dargestellt Funktion „reader()“. . Der Leserzahl (rc) wird erhöht, bevor das erreicht wird Mutex-Sperre . Es benutzt pthread_cond_wait() darauf warten bzgl. Zustand Variable, wenn es die ist erster Leser (rc == 1) . Dies hat zur Folge, dass Autoren am Schreiben gehindert werden, bis alle Leser mit dem Schreiben fertig sind.

Der Lesevorgang prüft, ob dies der Fall war letzter Leser (rc == 0) und senkt den Leser zählen (rc--) nach dem Lesen der freigegebenen Daten. Wenn es war, pthread_cond_signal() signalisiert die bzgl. Zustand Variable, um wartende Schreibprozesse fortzusetzen.

Verwendung der pthread_create() Und pthread_join()-Funktionen , Wir neu Und verbinden mehrere Leserthreads im Hauptfunktion . Zur Identifizierung wird jedem Leser-Thread eine individuelle ID zugewiesen.

Schreibprozess:

 wait(wrt); . . WRITE INTO THE OBJECT . signal(wrt); 

Im obigen Beispiel dasselbe wie Leserprozess , wird eine Operation ausgeführt, die als Warteoperation bezeichnet wird 'wrt' wenn ein Benutzer auf die Daten oder das Objekt zugreifen möchte. Danach kann der neue Benutzer nicht mehr auf das Objekt zugreifen. Und sobald der Benutzer mit dem Schreiben fertig ist, wird eine weitere Signaloperation ausgeführt bzgl .

2. Sperr- und Entsperrproblem:

Die Idee eines Mutex wird beim Multithreading in C verwendet, um sicherzustellen, dass es keine gibt Rennbedingung zwischen den Threads . Wenn mehrere Threads gleichzeitig mit der Verarbeitung derselben Daten beginnen, wird dieser Umstand als bezeichnet Rennen . Wenn diese Umstände jedoch vorliegen, müssen wir. Wir benutzen das Mutex-Sperre() Und unlock()-Funktionen um einen bestimmten Codeabschnitt für einen bestimmten Thread zu sichern. Dies bedeutet, dass ein anderer Thread nicht mit der Ausführung derselben Operation beginnen kann. Der 'kritischer Abschnitt/kritische Region' ist der Name dieses geschützten Codebereichs. Bevor wir die gemeinsam genutzten Ressourcen nutzen, richten wir in einem bestimmten Bereich viel ein und wenn wir sie nicht mehr nutzen, schalten wir sie wieder frei.

Lassen Sie uns die Funktionsweise des Mutex zum Sperren und Entsperren beim Multithreading in C untersuchen:

Beispiel:

 #include #include #include pthread_mutex_tmy_mutex = PTHREAD_MUTEX_INITIALIZER; int shared_data = 0; void *thread_function(void *arg) { pthread_mutex_lock(&amp;my_mutex); shared_data++; // Modify the shared data printf(&apos;Thread %ld: Shared data modified. New value: %d
&apos;, (long)arg, shared_data); pthread_mutex_unlock(&amp;my_mutex); return NULL; } int main() { pthread_tthreads[5]; // Assuming 5 threads for (int i = 0; i<5; i++) { if (pthread_create(&threads[i], null, thread_function, (void *)(long)(i + 1)) !="0)" fprintf(stderr, \'error creating thread %d
\', i 1); return 1; } for (int i< 5; (pthread_join(threads[i], null) joining 0; < pre> <p> <strong>Output:</strong> </p> <pre> Thread 1: Shared data modified. New value: 1 Thread 2: Shared data modified. New value: 2 Thread 3: Shared data modified. New value: 3 Thread 4: Shared data modified. New value: 4 Thread 5: Shared data modified. New value: 5 </pre> <p> <strong>Explanation:</strong> </p> <p>In this above example, we explain how we <strong> <em>lock</em> </strong> and <strong> <em>unlock</em> </strong> a certain region of code that shields us from the racing situation. <strong> <em>&apos;pthread_mutex_t&apos;</em> </strong> is used as an <strong> <em>initializer</em> </strong> in the example above. <strong> <em>&apos;pthread_mutex_lock&apos;</em> </strong> is then <strong> <em>written</em> </strong> before the beginning of the code that we want to lock. The coding that we wish to lock is finished after that. After that, the locking of the code is terminated using <strong> <em>&apos;pthread_mutex_unlock&apos;</em> </strong> ; going forward, no code will be in lock mode.</p> <h2>The Dining Philosopher Problem:</h2> <p>One of the classic issues with synchronization is the <strong> <em>dining philosopher issue</em> </strong> . Simple resource allocation for several processes is required but shouldn&apos;t result in a <strong> <em>stalemate</em> </strong> or <strong> <em>hunger</em> </strong> . The <strong> <em>dining philosopher problem</em> </strong> can be viewed as a straightforward representation of a number of processes, each of which is demanding resources. Since each of these processes requires a resource allocation, it is necessary to distribute those resources across all of the processes so that no one process ever gets stuck or stops working.</p> <p>Assume there are five philosophers seated at a <strong> <em>circle-shaped table</em> </strong> . They eat at one point and ponder about something at another. Around the round table, the philosophers are evenly spaced out on the chairs. Additionally, there is a bowl of rice and five chopsticks for each philosopher in the middle of the table. When the philosopher feels she cannot interact with her colleagues who are seated nearby.</p> <p>A philosopher occasionally takes up two chopsticks when she becomes hungry. She chooses two chopsticks from her neighbors-one on her <strong> <em>left</em> </strong> and one on her <strong> <em>right</em> </strong> -that are within easy reach. But the philosopher should never pick up more than one chopstick at once. She will obviously be unable to pick up the chopstick that the neighbor is using.</p> <p> <strong>Example:</strong> </p> <p>Let&apos;s use an example to demonstrate how this is implemented in C.</p> <pre> #include #include #include #include #include pthread_tphilosopher[5]; pthread_mutex_tchopstick[5]; void *func(void *arg) { int n = *(int *)arg; printf(&apos;
Philosopher %d is thinking.&apos;, n); pthread_mutex_lock(&amp;chopstick[n]); pthread_mutex_lock(&amp;chopstick[(n + 1) % 5]); printf(&apos;
Philosopher %d is eating.&apos;, n); sleep(3); pthread_mutex_unlock(&amp;chopstick[n]); pthread_mutex_unlock(&amp;chopstick[(n + 1) % 5]); printf(&apos;
Philosopher %d Finished eating &apos;, n); return NULL; } int main() { int i, k; void *message; for (i = 0; i<5; i++) { k="pthread_mutex_init(&amp;chopstick[i]," null); if (k !="0)" printf(\'failed to initialize the mutex
\'); exit(1); } for (i="0;" i< 5; null, func, (void *)&i); printf(\'error in thread creation.
\'); &message); join thread.
\'); printf(\'mutex destroyed.
\'); return 0; < pre> <p> <strong>Output:</strong> </p> <pre> Philosopher 0 is thinking. Philosopher 1 is thinking. Philosopher 2 is thinking. Philosopher 3 is thinking. Philosopher 4 is thinking. Philosopher 0 is eating. Philosopher 1 is eating. Philosopher 2 is eating. Philosopher 3 is eating. Philosopher 4 is eating. Philosopher 0 Finished eating Philosopher 1 Finished eating Philosopher 2 Finished eating Philosopher 3 Finished eating Philosopher 4 Finished eating </pre> <p> <strong>Explanation:</strong> </p> <p> <strong> <em>Chopsticks</em> </strong> can be represented by a semaphore. Since there are <strong> <em>chopsticks</em> </strong> on the table and no philosopher has chosen one, all of the chopsticks&apos; components are first initialized to <strong> <em>1</em> </strong> . Now that <strong> <em>chopstick[i]</em> </strong> has been chosen as the first <strong> <em>chopstick. chopstick[i]</em> </strong> and <strong> <em>chopstick[(i+1)%5]</em> </strong> are subject to the first wait operation. These <strong> <em>chopsticks&apos; wait operation</em> </strong> indicates that the philosopher has picked them up. The eating process begins once the philosopher selects his <strong> <em>chopstick</em> </strong> . The signal operation is now carried out on the <strong> <em>chopsticks [i]</em> </strong> and <strong> <em>[(i+1)%5]</em> </strong> once the philosopher has finished eating. The philosopher then turns back to sleep.</p> <p>To determine whether the <strong> <em>subthread</em> </strong> has joined the main thread or not, we used the <strong> <em>pthread_join function</em> </strong> . Similarly, we have checked whether the <strong> <em>mutex</em> </strong> lock has been initialized using the <strong> <em>pthread_mutex_init</em> </strong> method.</p> <p>To initialize and verify whether the new thread was created or not, we utilized the <strong> <em>pthread_create function</em> </strong> . Similar to this, we destroyed the <strong> <em>mutex lock</em> </strong> using the <strong> <em>pthread_mutex_destroy</em> </strong> function.</p> <h2>The Producer-Consumer Problem:</h2> <p>A common issue with multithreading process synchronization is the <strong> <em>producer-consumer problem</em> </strong> . Two processes are present in it: the first is the <strong> <em>producer&apos;s process</em> </strong> , and the second is the <strong> <em>consumer&apos;s process</em> </strong> . Furthermore, it is assumed that both operations are occurring concurrently in parallel. Additionally, they are a cooperative process, which implies that they are sharing something with one another. It is important that when the buffer is <strong> <em>full</em> </strong> , the producer cannot add data. When the buffer is empty, the consumer cannot extract data from the buffer because the common buffer size between the producer and the consumer is <strong> <em>fixed</em> </strong> . The issue is stated in this way. Hence, to implement the Producer-Consumer problem and solve it, we shall employ the idea of parallel programming.</p> <p> <strong>Example:</strong> </p> <pre> #include #include int mutex = 1, full = 0, empty = 3, x = 0; int main() { int n; void producer(); void consumer(); int wait(int); int signal(int); printf(&apos;
1.producer
2.consumer
3.for exit&apos;); while (1) { printf(&apos;
 Please enter your choice:&apos;); scanf(&apos;%d&apos;, &amp;n); switch (n) { case 1: if ((mutex == 1) &amp;&amp; (empty != 0)) producer(); else printf(&apos;Oops!! the buffer is full!!&apos;); break; case 2: if ((mutex == 1) &amp;&amp; (full != 0)) consumer(); else printf(&apos;Oops!! the buffer is empty!!&apos;); break; case 3: exit(0); break; } } return 0; } int wait(int s) { return (--s); } int signal(int s) { return (++s); } void producer() { mutex = wait(mutex); full = signal(full); empty = wait(empty); x++; printf(&apos;
Item produced by the Producer %d&apos;, x); mutex = signal(mutex); } void consumer() { mutex = wait(mutex); full = wait(full); empty = signal(empty); printf(&apos;
Item consumed by the Consumer %d&apos;, x); x--; mutex = signal(mutex); } </pre> <p> <strong>Output:</strong> </p> <pre> 1. producer 2. consumer 3. for exit Please enter your choice: </pre> <p> <strong>Explanation:</strong> </p> <p>We perform two tasks. The functions <strong> <em>consumer()</em> </strong> and <strong> <em>producer()</em> </strong> indicate the status and operation of the <strong> <em>consumer</em> </strong> and <strong> <em>producer</em> </strong> . The <strong> <em>producer() method</em> </strong> will create the <strong> <em>mutex lock</em> </strong> and determine whether the buffer is <strong> <em>full</em> </strong> when it is called. When the buffer is full, nothing will be produced. If not, it will <strong> <em>create</em> </strong> , and then, after the <strong> <em>production</em> </strong> , it will put itself to sleep to unlock the <strong> <em>mutex lock</em> </strong> . Like the <strong> <em>producer</em> </strong> , the consumer first creates the <strong> <em>mutex lock</em> </strong> , checks the <strong> <em>buffer</em> </strong> , consumes the <strong> <em>product</em> </strong> , and then releases the lock before going back to sleep.</p> <p>A <strong> <em>counter (x)</em> </strong> will be used during manufacturing and will keep growing until the manufacturer produces the item. However, the consumer will make fewer of the same manufactured <strong> <em>item (x)</em> </strong> .</p> <h2>Conclusion:</h2> <p>The idea of using <strong> <em>two</em> </strong> or <strong> <em>more threads</em> </strong> to execute a program is known as <strong> <em>multithreading</em> </strong> in the C programming language. <strong> <em>Multithreading</em> </strong> allows for the simultaneous execution of several tasks. The simplest executable component of a program is a <strong> <em>thread</em> </strong> . The process is the idea that a task can be completed by breaking it up into several smaller <strong> <em>sub-processes</em> </strong> .</p> <p>The header file <strong> <em>pthread.h</em> </strong> is required in order to implement multithreading in C since it cannot be done directly.</p> <hr></5;></pre></5;>

Erläuterung:

jframe

In diesem Beispiel oben erklären wir, wie wir sperren Und Freischalten ein bestimmter Codebereich, der uns vor der Rennsituation schützt. 'pthread_mutex_t' wird als verwendet Initialisierer im Beispiel oben. 'pthread_mutex_lock' ist dann geschrieben vor dem Anfang des Codes, den wir sperren möchten. Danach ist die Codierung, die wir sperren möchten, abgeschlossen. Danach wird die Sperrung des Codes mit beendet 'pthread_mutex_unlock' ; Künftig wird sich kein Code mehr im Sperrmodus befinden.

Das Problem des Essphilosophen:

Eines der klassischen Probleme bei der Synchronisierung ist die Problem der Essphilosophen . Eine einfache Ressourcenzuweisung für mehrere Prozesse ist erforderlich, sollte jedoch nicht zu einem Ergebnis führen Patt oder Hunger . Der Problem des Speisephilosophen kann als einfache Darstellung einer Reihe von Prozessen betrachtet werden, von denen jeder Ressourcen beansprucht. Da jeder dieser Prozesse eine Ressourcenzuweisung erfordert, ist es notwendig, diese Ressourcen auf alle Prozesse zu verteilen, damit kein Prozess jemals hängen bleibt oder nicht mehr funktioniert.

Angenommen, es sitzen fünf Philosophen an einem Tisch runder Tisch . An einem Punkt essen sie und denken an einem anderen Punkt über etwas nach. Rund um den runden Tisch sitzen die Philosophen gleichmäßig verteilt auf den Stühlen. Zusätzlich stehen in der Mitte des Tisches für jeden Philosophen eine Schüssel Reis und fünf Essstäbchen. Wenn die Philosophin das Gefühl hat, dass sie nicht mit ihren in der Nähe sitzenden Kollegen interagieren kann.

Eine Philosophin greift gelegentlich zu zwei Stäbchen, wenn sie hungrig wird. Sie wählt zwei Stäbchen von ihren Nachbarn aus – eines bei sich links und einer auf sie Rechts -die leicht zu erreichen sind. Aber der Philosoph sollte nie mehr als ein Stäbchen auf einmal in die Hand nehmen. Sie wird es offensichtlich nicht schaffen, das Essstäbchen aufzuheben, das der Nachbar benutzt.

Beispiel:

Lassen Sie uns anhand eines Beispiels demonstrieren, wie dies in C implementiert wird.

 #include #include #include #include #include pthread_tphilosopher[5]; pthread_mutex_tchopstick[5]; void *func(void *arg) { int n = *(int *)arg; printf(&apos;
Philosopher %d is thinking.&apos;, n); pthread_mutex_lock(&amp;chopstick[n]); pthread_mutex_lock(&amp;chopstick[(n + 1) % 5]); printf(&apos;
Philosopher %d is eating.&apos;, n); sleep(3); pthread_mutex_unlock(&amp;chopstick[n]); pthread_mutex_unlock(&amp;chopstick[(n + 1) % 5]); printf(&apos;
Philosopher %d Finished eating &apos;, n); return NULL; } int main() { int i, k; void *message; for (i = 0; i<5; i++) { k="pthread_mutex_init(&amp;chopstick[i]," null); if (k !="0)" printf(\'failed to initialize the mutex
\'); exit(1); } for (i="0;" i< 5; null, func, (void *)&i); printf(\'error in thread creation.
\'); &message); join thread.
\'); printf(\'mutex destroyed.
\'); return 0; < pre> <p> <strong>Output:</strong> </p> <pre> Philosopher 0 is thinking. Philosopher 1 is thinking. Philosopher 2 is thinking. Philosopher 3 is thinking. Philosopher 4 is thinking. Philosopher 0 is eating. Philosopher 1 is eating. Philosopher 2 is eating. Philosopher 3 is eating. Philosopher 4 is eating. Philosopher 0 Finished eating Philosopher 1 Finished eating Philosopher 2 Finished eating Philosopher 3 Finished eating Philosopher 4 Finished eating </pre> <p> <strong>Explanation:</strong> </p> <p> <strong> <em>Chopsticks</em> </strong> can be represented by a semaphore. Since there are <strong> <em>chopsticks</em> </strong> on the table and no philosopher has chosen one, all of the chopsticks&apos; components are first initialized to <strong> <em>1</em> </strong> . Now that <strong> <em>chopstick[i]</em> </strong> has been chosen as the first <strong> <em>chopstick. chopstick[i]</em> </strong> and <strong> <em>chopstick[(i+1)%5]</em> </strong> are subject to the first wait operation. These <strong> <em>chopsticks&apos; wait operation</em> </strong> indicates that the philosopher has picked them up. The eating process begins once the philosopher selects his <strong> <em>chopstick</em> </strong> . The signal operation is now carried out on the <strong> <em>chopsticks [i]</em> </strong> and <strong> <em>[(i+1)%5]</em> </strong> once the philosopher has finished eating. The philosopher then turns back to sleep.</p> <p>To determine whether the <strong> <em>subthread</em> </strong> has joined the main thread or not, we used the <strong> <em>pthread_join function</em> </strong> . Similarly, we have checked whether the <strong> <em>mutex</em> </strong> lock has been initialized using the <strong> <em>pthread_mutex_init</em> </strong> method.</p> <p>To initialize and verify whether the new thread was created or not, we utilized the <strong> <em>pthread_create function</em> </strong> . Similar to this, we destroyed the <strong> <em>mutex lock</em> </strong> using the <strong> <em>pthread_mutex_destroy</em> </strong> function.</p> <h2>The Producer-Consumer Problem:</h2> <p>A common issue with multithreading process synchronization is the <strong> <em>producer-consumer problem</em> </strong> . Two processes are present in it: the first is the <strong> <em>producer&apos;s process</em> </strong> , and the second is the <strong> <em>consumer&apos;s process</em> </strong> . Furthermore, it is assumed that both operations are occurring concurrently in parallel. Additionally, they are a cooperative process, which implies that they are sharing something with one another. It is important that when the buffer is <strong> <em>full</em> </strong> , the producer cannot add data. When the buffer is empty, the consumer cannot extract data from the buffer because the common buffer size between the producer and the consumer is <strong> <em>fixed</em> </strong> . The issue is stated in this way. Hence, to implement the Producer-Consumer problem and solve it, we shall employ the idea of parallel programming.</p> <p> <strong>Example:</strong> </p> <pre> #include #include int mutex = 1, full = 0, empty = 3, x = 0; int main() { int n; void producer(); void consumer(); int wait(int); int signal(int); printf(&apos;
1.producer
2.consumer
3.for exit&apos;); while (1) { printf(&apos;
 Please enter your choice:&apos;); scanf(&apos;%d&apos;, &amp;n); switch (n) { case 1: if ((mutex == 1) &amp;&amp; (empty != 0)) producer(); else printf(&apos;Oops!! the buffer is full!!&apos;); break; case 2: if ((mutex == 1) &amp;&amp; (full != 0)) consumer(); else printf(&apos;Oops!! the buffer is empty!!&apos;); break; case 3: exit(0); break; } } return 0; } int wait(int s) { return (--s); } int signal(int s) { return (++s); } void producer() { mutex = wait(mutex); full = signal(full); empty = wait(empty); x++; printf(&apos;
Item produced by the Producer %d&apos;, x); mutex = signal(mutex); } void consumer() { mutex = wait(mutex); full = wait(full); empty = signal(empty); printf(&apos;
Item consumed by the Consumer %d&apos;, x); x--; mutex = signal(mutex); } </pre> <p> <strong>Output:</strong> </p> <pre> 1. producer 2. consumer 3. for exit Please enter your choice: </pre> <p> <strong>Explanation:</strong> </p> <p>We perform two tasks. The functions <strong> <em>consumer()</em> </strong> and <strong> <em>producer()</em> </strong> indicate the status and operation of the <strong> <em>consumer</em> </strong> and <strong> <em>producer</em> </strong> . The <strong> <em>producer() method</em> </strong> will create the <strong> <em>mutex lock</em> </strong> and determine whether the buffer is <strong> <em>full</em> </strong> when it is called. When the buffer is full, nothing will be produced. If not, it will <strong> <em>create</em> </strong> , and then, after the <strong> <em>production</em> </strong> , it will put itself to sleep to unlock the <strong> <em>mutex lock</em> </strong> . Like the <strong> <em>producer</em> </strong> , the consumer first creates the <strong> <em>mutex lock</em> </strong> , checks the <strong> <em>buffer</em> </strong> , consumes the <strong> <em>product</em> </strong> , and then releases the lock before going back to sleep.</p> <p>A <strong> <em>counter (x)</em> </strong> will be used during manufacturing and will keep growing until the manufacturer produces the item. However, the consumer will make fewer of the same manufactured <strong> <em>item (x)</em> </strong> .</p> <h2>Conclusion:</h2> <p>The idea of using <strong> <em>two</em> </strong> or <strong> <em>more threads</em> </strong> to execute a program is known as <strong> <em>multithreading</em> </strong> in the C programming language. <strong> <em>Multithreading</em> </strong> allows for the simultaneous execution of several tasks. The simplest executable component of a program is a <strong> <em>thread</em> </strong> . The process is the idea that a task can be completed by breaking it up into several smaller <strong> <em>sub-processes</em> </strong> .</p> <p>The header file <strong> <em>pthread.h</em> </strong> is required in order to implement multithreading in C since it cannot be done directly.</p> <hr></5;>

Erläuterung:

Essstäbchen kann durch ein Semaphor dargestellt werden. Weil dort sind Essstäbchen Auf dem Tisch liegt und kein Philosoph sich für eines entschieden hat, werden zunächst alle Bestandteile der Stäbchen initialisiert 1 . Nun das Essstäbchen[i] wurde als erstes ausgewählt Stäbchen. Essstäbchen[i] Und Essstäbchen[(i+1)%5] unterliegen der ersten Warteoperation. Diese Wartevorgang der Essstäbchen zeigt an, dass der Philosoph sie aufgegriffen hat. Der Essprozess beginnt, sobald der Philosoph sein eigenes auswählt Stäbchen . Die Signaloperation wird nun am ausgeführt Essstäbchen [i] Und [(i+1)%5] sobald der Philosoph mit dem Essen fertig ist. Dann schläft der Philosoph wieder ein.

Um festzustellen, ob die Unterthread ob er dem Hauptthread beigetreten ist oder nicht, wir haben das verwendet pthread_join-Funktion . Ebenso haben wir geprüft, ob die Mutex Die Sperre wurde mit initialisiert pthread_mutex_init Methode.

Um zu initialisieren und zu überprüfen, ob der neue Thread erstellt wurde oder nicht, haben wir Folgendes verwendet pthread_create-Funktion . Ähnlich haben wir das zerstört Mutex-Sperre Verwendung der pthread_mutex_destroy Funktion.

Zahl zum String Java

Das Producer-Consumer-Problem:

Ein häufiges Problem bei der Synchronisierung von Multithreading-Prozessen ist das Produzenten-Konsumenten-Problem . Darin sind zwei Prozesse vorhanden: Der erste ist der Prozess des Produzenten , und der zweite ist der Verbraucherprozess . Darüber hinaus wird davon ausgegangen, dass beide Vorgänge gleichzeitig und parallel stattfinden. Darüber hinaus handelt es sich um einen kooperativen Prozess, was bedeutet, dass sie etwas miteinander teilen. Es ist wichtig, dass der Puffer vorhanden ist voll , kann der Produzent keine Daten hinzufügen. Wenn der Puffer leer ist, kann der Verbraucher keine Daten aus dem Puffer extrahieren, da die gemeinsame Puffergröße zwischen dem Produzenten und dem Verbraucher gleich ist Fest . Das Problem wird auf diese Weise dargelegt. Um das Producer-Consumer-Problem umzusetzen und zu lösen, werden wir daher die Idee der parallelen Programmierung anwenden.

Beispiel:

 #include #include int mutex = 1, full = 0, empty = 3, x = 0; int main() { int n; void producer(); void consumer(); int wait(int); int signal(int); printf(&apos;
1.producer
2.consumer
3.for exit&apos;); while (1) { printf(&apos;
 Please enter your choice:&apos;); scanf(&apos;%d&apos;, &amp;n); switch (n) { case 1: if ((mutex == 1) &amp;&amp; (empty != 0)) producer(); else printf(&apos;Oops!! the buffer is full!!&apos;); break; case 2: if ((mutex == 1) &amp;&amp; (full != 0)) consumer(); else printf(&apos;Oops!! the buffer is empty!!&apos;); break; case 3: exit(0); break; } } return 0; } int wait(int s) { return (--s); } int signal(int s) { return (++s); } void producer() { mutex = wait(mutex); full = signal(full); empty = wait(empty); x++; printf(&apos;
Item produced by the Producer %d&apos;, x); mutex = signal(mutex); } void consumer() { mutex = wait(mutex); full = wait(full); empty = signal(empty); printf(&apos;
Item consumed by the Consumer %d&apos;, x); x--; mutex = signal(mutex); } 

Ausgabe:

 1. producer 2. consumer 3. for exit Please enter your choice: 

Erläuterung:

Wir führen zwei Aufgaben aus. Die Funktionen Verbraucher() Und Hersteller() zeigen den Status und den Betrieb des an Verbraucher Und Hersteller . Der Produzent()-Methode wird das erstellen Mutex-Sperre und bestimmen Sie, ob der Puffer vorhanden ist voll wenn es aufgerufen wird. Wenn der Puffer voll ist, wird nichts produziert. Wenn nicht, wird es so sein erstellen , und dann, nach dem Produktion , wird es sich selbst in den Ruhezustand versetzen, um das zu entsperren Mutex-Sperre . Wie Hersteller , erstellt der Verbraucher zunächst die Mutex-Sperre , prüft die Puffer , verbraucht die Produkt , und gibt dann die Sperre frei, bevor Sie wieder in den Ruhezustand wechseln.

A Zähler (x) wird während der Herstellung verwendet und wächst weiter, bis der Hersteller den Artikel produziert. Allerdings wird der Verbraucher weniger davon herstellen lassen Artikel (x) .

Abschluss:

Die Idee der Nutzung zwei oder weitere Threads Das Ausführen eines Programms wird als bezeichnet Multithreading in der Programmiersprache C. Multithreading ermöglicht die gleichzeitige Ausführung mehrerer Aufgaben. Die einfachste ausführbare Komponente eines Programms ist a Faden . Der Prozess ist die Idee, dass eine Aufgabe erledigt werden kann, indem man sie in mehrere kleinere aufteilt Teilprozesse .

Die Header-Datei pthread.h ist erforderlich, um Multithreading in C zu implementieren, da dies nicht direkt möglich ist.