logo

MONIKIERTO C:ssa

Esittely:

C:ssä termi 'monisäikeinen' kuvaa useiden käyttöä langat samanaikaisesti. Jokainen lanka tekee a eri tehtävä . Monisäikeen samanaikaisen luonteen vuoksi voidaan suorittaa useita tehtäviä kerralla. Lisäksi, monisäikeinen vähentää CPU:n resurssien käyttö . Moniajossa on kaksi luokkaa: prosessipohjainen ja lankapohjainen . Kun jotain kuvataan monisäikeiseksi, se tarkoittaa, että vähintään kaksi tai ehkä useampi säiettä on käynnissä samassa prosessissa kerralla. Meidän on ensin ymmärrettävä, mitä säie ja prosessi ovat, jotta voimme ymmärtää monisäikeisyyden C:ssä. Katsotaanpa näitä aiheita saadaksemme paremman käsityksen.

sed-komento

Mitä ovat prosessit ja säikeet?

A lanka on perusrakennus lohko minkä tahansa prosessin suorittamisesta. Ohjelma koostuu useista prosesseista, ja jokainen prosessi koostuu säikeistä, jotka ovat paljon perusyksiköitä. Siksi säiettä voidaan pitää prosessin perustavanlaatuisena rakennuspalikkana tai yksinkertaisempana yksikkönä, joka yhdessä määrää CPU:n käytön.

Seuraavat kohteet sisältyvät säikeeseen:

Viestiketjun tunnus:

Se on erityinen säikeen tunnus joka luodaan säiettä muodostettaessa ja säilytetään kyseisen säikeen keston ajan.

Ohjelmalaskuri:

Se on arvo, jonka laitteisto latautuu .

Rekisteröity sarja:

Se on kokoelma yhteiset rekisterit .

Pino:

Se on jäännös siitä tietty lanka .

Lisäksi, jos kaksi säiettä toimii samanaikaisesti samassa prosessissa, ne jakavat koodi , tietoosiot , ja muut käyttöjärjestelmäresurssit, kuten tiedosto avautuu ja signaaleja . Raskas prosessi, eräänlainen perinteinen prosessi, voi ohjata yhtä säiettä. Monisäikeinen ohjaus pystyy kuitenkin avaamaan ja suorittamaan useita tehtäviä samanaikaisesti. Järjestelmästä tulee huomattavasti tehokkaampi lankojen käytön seurauksena, minkä vuoksi niistä on hyötyä.

Ero välillä yksittäinen ja monisäikeinen C:ssä on selitetty. Ensinnäkin se on a yksisäikeinen prosessi . Tämän seurauksena koko lohko - mukaan lukien koodi, data, jne. - pidetään yhtenä prosessina, ja sillä on vain yksi säie. Se tarkoittaa, että tämä tekniikka suorittaa vain yhden tehtävän kerrallaan. Mutta siellä on a monisäikeinen prosessi joka vastustaa tätä. Toimintaa on mm koodi, pino, data , ja tiedostot samoin, mutta niitä suorittavat useat säikeet, joista jokaisella on oma pinonsa ja rekisterinsä. Koska tässä tilanteessa voidaan suorittaa useita tehtäviä kerralla, prosessi tunnetaan nimellä a monisäikeinen prosessi .

Lankaa on kahta erilaista:

Viesti käyttäjätasolla:

Se on käyttäjätasolla, kuten nimestä voi päätellä. Ytimelle ei anneta pääsyä tietoihinsa.

Lanka ytimen tasolla

Säikeen tyyppi viittaa säikeen suhteeseen ytimeen ja järjestelmän käyttöjärjestelmään.

Käsitellä asiaa- Ohjelman toteuttamiseen suoritettujen vaiheiden sarjaa voidaan kutsua nimellä käsitellä asiaa . Ohjelmaa ei suoriteta heti, kun se ajetaan. Se on jaettu muutamaan perusvaiheeseen, jotka suoritetaan peräkkäin organisoidulla tavalla, mikä johtaa lopulta prosessin suorittamiseen.

Prosessia, joka on jaettu pienempiin vaiheisiin, kutsutaan a 'klooni tai lapsiprosessi', kun taas alkuperäistä prosessia kutsutaan nimellä 'vanhempi' prosessi . Jokainen prosessi käyttää muistissa tietyn määrän tilaa, jota ei jaeta muiden prosessien kanssa.

Menettely käy läpi joitakin vaiheita ennen suoritusta.

UUSI-

Tässä tilanteessa on uusi prosessi luotu .

kuinka monta 0 miljardista

VALMIS-

Kun prosessi on valmisteltu ja odottaa prosessorin osoittamista, se on tässä tilassa.

JUOKSU-

Kun prosessi on aktiivinen, se on tila.

ODOTTAA-

Kun prosessi on tässä tilassa, jotain on odottaa tapahtua.

PÄÄTTYNYT-

Se on tila, jossa menettely suoritetaan.

Miksi C on monisäikeinen?

Monisäikeinen C-ajatuksessa voidaan hyödyntää rinnakkaisuuden kautta an sovelluksen toiminnallisuutta . Harkitse tapausta, jossa selainikkunassa on auki useita välilehtiä. Sitten jokainen välilehti toimii samanaikaisesti ja niihin voidaan viitata nimellä a Lanka . Olettaen, että käytämme Microsoft Excel , yksi säie selviää tekstin muotoilu , ja yksi lanka tulee käsittele syöttöä . Siksi C:n monisäikeinen ominaisuus helpottaa useiden tehtävien suorittamista kerralla. Langan luominen on huomattavasti nopeampaa. Kontekstin siirto säikeiden välillä tapahtuu nopeammin. Lisäksi kommunikointi säikeiden välillä voidaan tehdä nopeammin ja säikeen päättäminen on helppoa.

Kuinka kirjoittaa C-ohjelmia monisäikeistykseen?

Vaikka monisäikeisiä sovelluksia ei ole sisäänrakennettu C-kieleen, se on mahdollista käyttöjärjestelmästä riippuen. The threads.h vakiokirjasto käytetään monisäikeisen idean toteuttamiseen C . Tällä hetkellä ei kuitenkaan ole olemassa kääntäjää, joka voisi tehdä tämän. Meidän on käytettävä alustakohtaisia ​​toteutuksia, kuten 'POSIX' säikeitä kirjasto, käyttämällä otsikkotiedostoa pthread.h , jos haluamme käyttää monisäikeistystä C:ssä. 'Pthreads' on toinen nimi tälle. A POSIX lanka voidaan luoda seuraavilla tavoilla:

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

Tässä tapauksessa, Pthread_create luo uuden säikeen tehdäkseen säikeestä suoritettavan. Sen avulla voit toteuttaa monisäikeistyksen C:ssä niin monta kertaa kuin haluat koodissasi. Aiemmat parametrit ja niiden kuvaukset on lueteltu tässä.

verkko ja internet

lanka:

Se on a yksittäinen tunnistus että aliprosessi palauttaa .

attr:

Kun haluamme asettaa säikeen attribuutteja, käytämme tätä läpinäkymätön attribuutti .

start_rutine:

Kun aloitus_rutiini on luotu, säie suorittaa rutiinin.

arg:

Parametri, joka aloitus_rutiini saa. TYHJÄ käytetään, jos argumentteja ei anneta.

Tietyt C-monisäikeiset esimerkit

Tässä on esimerkkejä C:n monisäikeistysongelmista.

1. Lukija-kirjoittaja -ongelma

Yleinen käyttöjärjestelmäongelma prosessin synkronoinnissa on lukija/kirjoittaja ongelma . Oletetaan, että meillä on sellainen tietokanta Lukijat ja kirjailijat , kaksi eri käyttäjäluokkaa, voivat käyttää. Lukijat ovat ainoita, jotka voivat lukea tietokanta, kun taas kirjailijat ovat ainoita, jotka voivat lukea tietokannan ja päivittää sitä. Käytetään IRCTC yksinkertaisena esimerkkinä. Jos haluamme tarkistaa tietyn tilan junan numero , syötä vain junan numero järjestelmään nähdäksesi asiaankuuluvat junatiedot. Tässä näytetään vain verkkosivustolla olevat tiedot. Lukuoperaattori on tämä. Jos kuitenkin haluamme varata lipun, meidän on täytettävä lipun varauslomake sellaisilla tiedoilla kuin nimemme, ikämme ja niin edelleen. Suoritamme siis kirjoitustoiminnon täällä. Mukaan tehdään joitain säätöjä IRCTC-tietokanta .

Ongelmana on, että useat ihmiset yrittävät samanaikaisesti päästä käsiksi IRCTC-tietokanta . Ne voivat olla a kirjailija tai a lukija . Ongelma syntyy, jos lukija käyttää jo tietokantaa ja kirjoittaja käyttää sitä samanaikaisesti työstääkseen samaa dataa. Toinen ongelma syntyy, kun kirjoittaja käyttää tietokantaa ja lukija käyttää samoja tietoja kuin tietokanta. Kolmanneksi on olemassa vaikeuksia, kun yksi kirjoittaja päivittää tietokantaa, kun toinen yrittää päivittää tietoja samassa tietokannassa. Neljäs skenaario tapahtuu, kun kaksi lukijaa yrittää hakea samaa materiaalia. Kaikki nämä ongelmat syntyvät, jos lukija ja kirjoittaja käyttävät samoja tietokantatietoja.

Semafori on menetelmä, jota käytetään tämän ongelman ratkaisemiseen. Katsotaanpa esimerkkiä tämän ongelman käyttämisestä.

Lukijaprosessi:

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

Selitys:

Tässä koodissa meillä on jaetut muuttujatiedot ja lukijamäärä rc . The wrt kunto muuttujaa käytetään rajoittamaan pääsyä kirjoittajaprosessi , ja mutex käytetään takaamaan molemminpuolinen poissulkeminen jaettuun tietoon pääsystä.

Lukijaprosessia edustaa Reader()-funktio . The lukijamäärä (rc) korotetaan ennen kuin saavutetaan mutex-lukko . Se käyttää pthread_cond_wait() odottamaan wrt kunto muuttuja, jos se on ensimmäinen lukija (rc == 1) . Tämän seurauksena kirjoittajia estetään kirjoittamasta ennen kuin kaikki lukijat ovat kirjoittaneet.

Lukijaprosessi tarkistaa, oliko se viimeisin lukija (rc == 0) ja alentaa lukijaa laske (rc--) kun olet lukenut jaetut tiedot. Jos se oli, pthread_cond_signal() signaloi wrt kunto muuttuja antaa odottavien kirjoitusprosessien jatkua.

Käyttämällä pthread_create() ja pthread_join()-funktiot , me Uusi ja liittyä seuraan useita lukijaketjuja päätoiminto . Jokaiselle lukijasäikeelle on määritetty yksilöllinen tunnus tunnistamista varten.

Kirjoitusprosessi:

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

Yllä olevassa esimerkissä sama kuin lukijaprosessi , toiminto, joka tunnetaan nimellä odotustoiminto, suoritetaan 'wrt' kun käyttäjä haluaa käyttää tietoja tai esinettä. Sen jälkeen uusi käyttäjä ei voi käyttää objektia. Ja kun käyttäjä on lopettanut kirjoittamisen, suoritetaan toinen signaalitoiminto wrt .

2. Lukitse ja avaa -ongelma:

Ajatus a mutex käytetään monisäikeisessä C:ssä takaamaan, ettei a kilpailun kunto välissä langat . Kun useat säikeet alkavat käsitellä samaa dataa kerralla, tämä seikka tunnetaan nimellä kilpa- . Kuitenkin, jos nämä olosuhteet ovat olemassa, meidän on. Käytämme mutexin lukko() ja unlock()-funktiot varmistaaksesi tietyn koodiosan tietylle säikeelle. Sellaisena, että toinen säie ei voi alkaa suorittaa samaa toimintoa. The 'kriittinen osa/alue' on tälle suojatulle koodialueelle annettu nimi. Ennen kuin käytämme jaettuja resursseja, määritämme paljon tietylle alueelle, ja kun olemme lopettaneet niiden käytön, vapautamme ne vielä kerran.

Tarkastellaan mutexin toimintaa monisäikeisessä C:n lukitsemisessa ja avaamisessa:

Esimerkki:

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

Selitys:

java paluu komento

Tässä yllä olevassa esimerkissä selitämme, kuinka me Lukko ja avata tietty koodialue, joka suojaa meitä kilpailutilanteelta. 'pthread_mutex_t' käytetään alustus yllä olevassa esimerkissä. 'pthread_mutex_lock' on sitten kirjoitettu ennen sen koodin alkua, jonka haluamme lukita. Koodaus, jonka haluamme lukita, on valmis tämän jälkeen. Tämän jälkeen koodin lukitus lopetetaan käyttämällä 'pthread_mutex_unlock' ; jatkossa mikään koodi ei ole lukitustilassa.

Ruokailufilosofin ongelma:

Yksi synkronoinnin klassisista ongelmista on ruokailufilosofi kysymys . Yksinkertainen resurssien allokointi useille prosesseille vaaditaan, mutta sen ei pitäisi johtaa a umpikuja tai nälkä . The ruokailufilosofin ongelma voidaan nähdä suorana esityksenä useista prosesseista, joista jokainen vaatii resursseja. Koska jokainen näistä prosesseista vaatii resurssien allokoinnin, on välttämätöntä jakaa nämä resurssit kaikille prosesseille, jotta mikään prosessi ei koskaan jumiudu tai lakkaa toimimasta.

Oletetaan, että paikassa a istuu viisi filosofia ympyrän muotoinen pöytä . He syövät yhdessä vaiheessa ja pohtivat jotain toisessa. Pyöreän pöydän ympärillä filosofit ovat tasaisin välimatkoin tuoleilla. Lisäksi jokaiselle filosofille on pöydän keskellä kulho riisiä ja viisi syömäpuikkoa. Kun filosofi kokee, ettei hän voi olla vuorovaikutuksessa lähellä olevien kollegoidensa kanssa.

ohut algoritmi

Filosofi ottaa toisinaan kaksi syömäpuikkoa, kun hänellä tulee nälkä. Hän valitsee kaksi syömäpuikkoa naapureistaan ​​- yhden hänen päällänsä vasemmalle ja yksi hänestä oikein -jotka ovat helposti saavutettavissa. Mutta filosofin ei pitäisi koskaan poimia useampaa kuin yhtä syömäpuikkoa kerralla. Hän ei ilmeisesti pysty nostamaan naapurin käyttämää syömäpuikkoa.

Esimerkki:

Käytämme esimerkkiä sen osoittamiseen, kuinka tämä toteutetaan C:ssä.

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

Selitys:

Syömäpuikot voidaan esittää semaforilla. Koska niitä on syömäpuikot pöydällä eikä yksikään filosofi ole valinnut yhtä, kaikki syömäpuikon komponentit alustetaan ensin 1 . Nyt kun syömäpuikko[i] on valittu ensimmäiseksi syömäpuikko. syömäpuikko[i] ja syömäpuikko[(i+1)%5] ovat ensimmäisen odotusoperaation alaisia. Nämä syömäpuikkojen odotusoperaatio osoittaa, että filosofi on poiminut ne. Syömisprosessi alkaa, kun filosofi valitsee omansa syömäpuikko . Signaalitoiminto suoritetaan nyt laitteella syömäpuikot [i] ja [(i+1)%5] kun filosofi on syönyt. Filosofi nukahtaa sitten takaisin.

Sen määrittämiseksi, onko alasäie on liittynyt pääketjuun vai ei, käytimme pthread_join-funktio . Samalla tavalla olemme tarkistaneet, onko mutex lukko on alustettu käyttämällä pthread_mutex_init menetelmä.

Käytimme alustaaksesi ja tarkistaaksemme, luotiinko uusi säie vai ei pthread_create-funktio . Samoin tuhosimme mutex-lukko käyttämällä pthread_mutex_destroy toiminto.

Tuottaja-kuluttaja -ongelma:

Yleinen ongelma monisäikeisten prosessien synkronoinnissa on tuottaja-kuluttaja ongelma . Siinä on kaksi prosessia: ensimmäinen on tuottajan prosessi , ja toinen on kuluttajan prosessi . Lisäksi oletetaan, että molemmat toiminnot tapahtuvat samanaikaisesti rinnakkain. Lisäksi ne ovat yhteistyöprosessi, mikä tarkoittaa, että he jakavat jotain toistensa kanssa. On tärkeää, että kun puskuri on koko , tuottaja ei voi lisätä tietoja. Kun puskuri on tyhjä, kuluttaja ei voi poimia puskurista tietoja, koska tuottajan ja kuluttajan välinen yhteinen puskurin koko on korjattu . Asia ilmaistaan ​​tällä tavalla. Siten tuottaja-kuluttaja -ongelman toteuttamiseksi ja ratkaisemiseksi hyödynnämme rinnakkaisohjelmoinnin ideaa.

Esimerkki:

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

Lähtö:

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

Selitys:

Suoritamme kaksi tehtävää. Toiminnot kuluttaja() ja tuottaja() osoittavat tilan ja toiminnan kuluttaja ja tuottaja . The tuottaja() -menetelmä luo mutex-lukko ja määrittää, onko puskuri koko kun sitä kutsutaan. Kun puskuri on täynnä, mitään ei tuoteta. Jos ei, niin tulee luoda , ja sitten sen jälkeen tuotantoa , se nukahtaa avatakseen lukituksen mutex-lukko . Kuin tuottaja , kuluttaja luo ensin mutex-lukko , tarkistaa puskuri , kuluttaa tuote , ja vapauttaa sitten lukon ennen nukkumaan menoa.

A laskuri (x) käytetään valmistuksen aikana ja kasvaa, kunnes valmistaja valmistaa tuotteen. Kuluttaja tekee kuitenkin vähemmän samaa valmistettua kohde (x) .

Johtopäätös:

Idea käyttää kaksi tai lisää lankoja ohjelman suorittaminen tunnetaan nimellä monisäikeinen C-ohjelmointikielellä. Monisäikeinen mahdollistaa useiden tehtävien suorittamisen samanaikaisesti. Ohjelman yksinkertaisin suoritettava komponentti on a lanka . Prosessi on ajatus siitä, että tehtävä voidaan suorittaa jakamalla se useisiin pienempiin osiin osaprosesseja .

Otsikkotiedosto pthread.h tarvitaan monisäikeistyksen toteuttamiseen C:ssä, koska sitä ei voi tehdä suoraan.