logo

C'DE ÇOKLU İŞ İŞİ İŞLEME

Giriiş:

C'de terim 'çoklu iş parçacığı' çok sayıda kullanımını açıklar İş Parçacığı eşzamanlı. Her iş parçacığı bir işlem yapar farklı görev . Çoklu iş parçacığının eş zamanlı yapısı nedeniyle birçok görev aynı anda gerçekleştirilebilir. Bunlara ek olarak, çoklu iş parçacığı azaltır CPU'nun kaynak kullanımı . Çoklu görevin iki kategorisi vardır: süreç bazlı Ve iş parçacığı tabanlı . Herhangi bir şey çoklu iş parçacığı olarak tanımlandığında, bu, en az iki veya belki daha fazla iş parçacığının aynı anda aynı işlemde çalıştığı anlamına gelir. C'de çoklu iş parçacığını kavrayabilmek için öncelikle iş parçacığının ve sürecin ne olduğunu anlamamız gerekiyor. Daha iyi anlamak için bu konulara bakalım.

sed komutu

Süreçler ve iş parçacıkları nelerdir?

A iplik bu temel bina engellemek herhangi bir işlemin yürütülmesi. Bir program çeşitli işlemlerden oluşur ve her işlem çok daha temel birimler olan iş parçacıklarından oluşur. Bu nedenle iş parçacığı, bir işlemin temel yapı taşı veya CPU kullanımını ortaklaşa belirleyen daha basit birim olarak düşünülebilir.

Bir iş parçacığına aşağıdaki öğeler dahildir:

Konu kimliği:

Bu özel bir iş parçacığı kimliği iş parçacığı oluşumu sırasında oluşturulur ve söz konusu iş parçacığının süresi boyunca saklanır.

Program sayıcı:

Bu bir değerdir donanım yükleri .

Kayıtlı bir set:

Bu bir koleksiyon ortak kayıtlar .

Bir yığın:

Bu ondan bir kalıntı özel konu .

Ayrıca, eğer iki iş parçacığı aynı süreçte aynı anda çalışıyorsa, kod , veri bölümleri ve dosya gibi diğer işletim sistemi kaynakları açılır Ve sinyaller . Bir tür geleneksel işlem olan ağır bir işlem, bir iş parçacığını kontrol edebilir. Bununla birlikte, çoklu iş parçacığı kontrolü aynı anda birden fazla görevi açma ve yürütme kapasitesine sahiptir. İpliklerin kullanılması sonucunda sistem çok daha etkili hale gelir, bu nedenle faydalıdırlar.

Arasındaki fark Bekar Ve çoklu iş parçacığı C'de açıklanmıştır. Her şeyden önce bu bir tek iş parçacıklı işlem . Sonuç olarak, bloğun tamamı (buna dahil) kod, veri, vb.-tek bir süreç olarak kabul edilir ve bu sürecin yalnızca bir iş parçacığı vardır. Bu tekniğin aynı anda yalnızca bir görevi tamamlayacağı anlamına gelir. Ama bir şey var çoklu iş parçacıklı süreç bu da buna karşı çıkıyor. Gibi aktiviteler var kod, yığın, veri , Ve Dosyalar aynı zamanda, ancak her biri kendi yığınına ve yazmaçlarına sahip olan birkaç iş parçacığı tarafından gerçekleştirilirler. Bu durumda çok sayıda görevin aynı anda tamamlanabileceği göz önüne alındığında, süreç bir süreç olarak bilinir. çoklu iş parçacıklı süreç .

Konu iki çeşittir:

Kullanıcı düzeyinde konu:

Adından da anlaşılacağı gibi kullanıcı düzeyindedir. Çekirdeğe kendi verilerine erişim izni verilmez.

Çekirdek düzeyinde iş parçacığı

İş parçacığının türü, iş parçacığının çekirdekle ve sistemin işletim sistemiyle olan ilişkisini ifade eder.

İşlem- Bir programı gerçekleştirmek için atılan adımlar dizisine, işlem . Bir program çalıştırıldığında hemen yürütülmez. Sonunda bir sürecin yürütülmesine yol açmak için organize bir şekilde sırayla gerçekleştirilen birkaç temel adıma bölünmüştür.

Daha küçük adımlara bölünmüş bir sürece denir. 'klon veya alt süreç', orijinal süreç olarak anılırken 'ebeveyn' süreci . Bellekte her işlem, diğer işlemlerle paylaşılmayan belirli bir miktarda alan kullanır.

ABD'deki eyaletler

Bir prosedür yürütülmeden önce bazı aşamalardan geçer.

YENİ-

Bu durumda yeni bir süreç başlıyor. oluşturulan .

HAZIR-

Bir proses hazırlanıp bir işlemcinin atanmasını beklerken bu durumdadır.

KOŞMA-

Süreç aktif olduğunda durum budur.

BEKLEMEK-

Bir süreç bu durumda olduğunda, bir şey beklemek gerçekleşmesi için.

SONLANDIRILMIŞ-

Prosedürün yürütüldüğü durumdur.

C neden çok iş parçacıklı?

Çoklu iş parçacığı C fikrinde paralellik yoluyla bir geliştirme geliştirilebilir. uygulamanın işlevselliği . Bir tarayıcı penceresinde birden fazla sekmenin açık olduğu durumu düşünün. Daha sonra her sekme aynı anda çalışır ve bir sekme olarak adlandırılabilir. İplik . kullandığımızı varsayarsak Microsoft Excel , bir iş parçacığı yönetecek Metin biçimlendirme ve bir iş parçacığı girişi yönet . Bu nedenle C'nin çoklu iş parçacığı özelliği, birden fazla görevi aynı anda yürütmeyi kolaylaştırır. Bir iş parçacığının oluşturulması oldukça hızlıdır. İş parçacıkları arasında bağlam aktarımı daha hızlı gerçekleşir. Ek olarak, iş parçacıkları arasındaki iletişim daha hızlı yapılabilir ve iş parçacığının sonlandırılması basittir.

Çoklu İş Parçacığı için C Programları Nasıl Yazılır?

Çoklu iş parçacıklı uygulamalar C dilinde yerleşik olmasa da işletim sistemine bağlı olarak mümkündür. thread.h standart kütüphanesi çoklu iş parçacığı fikrini uygulamak için kullanılır C . Ancak şu anda bunu yapabilecek bir derleyici yok. gibi platforma özel uygulamaları kullanmalıyız. 'POSIX' başlık dosyasını kullanarak thread kütüphanesi pthread.h C'de çoklu iş parçacığı kullanmak istiyorsak. 'P-iplikleri' bunun diğer adıdır. A POSIX iş parçacığı aşağıdaki şekillerde oluşturulabilir:

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

Bu durumda, Pthread_create iş parçacığının çalıştırılabilir olmasını sağlamak için yeni bir iş parçacığı oluşturur. C'de çoklu iş parçacıklarını kodunuzda istediğiniz kadar uygulamanıza olanak tanır. Daha önceki parametreler ve bunların açıklamaları burada listelenmiştir.

iplik:

Bu bir tekil tanımlama bu alt süreç dönüşleri .

öznitelik:

İş parçacığı niteliklerini ayarlamak istediğimizde bunu kullanırız opak özellik .

start_routine:

Ne zaman start_routine oluşturulursa iş parçacığı bir rutin çalıştıracaktır.

argüman:

Parametre start_routine alır. HÜKÜMSÜZ Herhangi bir argüman verilmediği takdirde kullanılacaktır.

ikili ağaç vs bst

Belirli C çoklu iş parçacığı örnekleri

İşte C'deki çoklu iş parçacıklı sorunlara bazı örnekler.

1. Okuyucu-Yazar Sorunu

İşlem senkronizasyonu ile ilgili yaygın bir işletim sistemi sorunu, okuyucu/yazar sorunu . Diyelim ki elimizde bir veritabanı var Okuyucular Ve Yazarlar , iki farklı kullanıcı kategorisine erişim sağlayabilirsiniz. Okuyucular bunu yapabilen tek kişiler onlar Okumak veritabanı, oysa Yazarlar veritabanını okuyabilen ve güncelleyebilen tek kişiler onlardır. hadi kullanalım IRCTC basit bir örnek olarak. Belirli bir durumun durumunu kontrol etmek istersek tren numarası İlgili tren bilgilerini görüntülemek için sisteme tren numarasını girmeniz yeterlidir. Burada yalnızca web sitesinde bulunan bilgiler gösterilir. Okuma operatörü şudur. Ancak bilet ayırtmak istiyorsak bilet rezervasyon formunu adımız, yaşımız vb. bilgilerle doldurmamız gerekir. Yani burada bir yazma işlemi gerçekleştireceğiz. Bazı düzenlemeler yapılacak IRCTC veritabanı .

Sorun, birden fazla kişinin aynı anda erişmeye çalışmasıdır. IRCTC veritabanı . Onlar bir olabilir yazar veya bir okuyucu . Sorun, bir okuyucunun zaten veritabanını kullanması ve bir yazarın aynı veriler üzerinde çalışmak için aynı anda veritabanına erişmesi durumunda ortaya çıkar. Bir yazar bir veritabanı kullandığında ve okuyucu da veritabanıyla aynı bilgiye eriştiğinde başka bir sorun ortaya çıkar. Üçüncüsü, bir yazar veritabanını güncellerken diğerinin aynı veritabanındaki verileri güncellemeye çalışması sırasında zorluk yaşanır. Dördüncü senaryo, iki okuyucunun aynı materyali almaya çalışmasıyla ortaya çıkar. Tüm bu sorunlar, okuyucu ve yazarın aynı veritabanı verilerini kullanması durumunda ortaya çıkar.

Semafor bu sorunu çözmek için kullanılan bir yöntemdir. Bu sorunun nasıl kullanılacağını gösteren bir resme bakalım.

Okuyucu süreci:

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

Açıklama:

Bu kodda, paylaşılan değişken verilerine sahibiz ve okuyucu sayısı rc . wrt durumu değişken erişimi sınırlamak için kullanılır yazar süreci , ve muteks paylaşılan verilere erişimde karşılıklı dışlamayı garanti etmek için kullanılır.

Okuyucu süreci şu şekilde temsil edilir: okuyucu () işlevi . okuyucu sayısı (rc) ulaşılmadan önce artırılır. muteks kilidi . Kullanır pthread_cond_wait() beklemek wrt durumu değişken ise ilk okuyucu (rc == 1) . Sonuç olarak, tüm okuyucular tamamlayıncaya kadar yazarların yazması engellenecektir.

Okuyucu süreci bunun olup olmadığını kontrol eder. son okuyucu (rc == 0) ve okuyucuyu düşürür say (rc--) Paylaşılan verileri okuduktan sonra. Eğer öyle olsaydı pthread_cond_signal() sinyaller wrt durumu Bekleyen yazar işlemlerinin devam etmesine izin veren değişken.

Kullanmak pthread_create() Ve pthread_join() işlevleri , Biz yeni Ve katılmak birden fazla okuyucu dizisi ana işlev . Tanımlama amacıyla her okuyucu dizisine ayrı bir kimlik atanır.

Yazar süreci:

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

Yukarıdaki örnekte de aynı okuyucu süreci bekleme işlemi olarak bilinen bir işlem gerçekleştirilir. 'wrt' Bir kullanıcı verilere veya nesneye erişmek istediğinde. Bundan sonra yeni kullanıcı nesneye erişemeyecektir. Kullanıcı yazmayı bitirdikten sonra başka bir sinyal işlemi gerçekleştirilir. wrt .

2. kilitleme ve kilit açma sorunu:

Bir fikir muteks olmayacağını garanti etmek için C'de çoklu iş parçacığında kullanılır. yarış kondisyonu arasında İş Parçacığı . Birden fazla iş parçacığının aynı anda aynı veriyi işlemeye başlamasına bu durum denir. yarışma . Ancak bu koşullar mevcutsa mecburuz. biz kullanıyoruz mutex'in kilidi() Ve kilidini aç() işlevleri belirli bir iş parçacığı için belirli bir kod bölümünü güvence altına almak için. Öyle ki başka bir thread aynı işlemi yapmaya başlayamaz. 'kritik bölüm/bölge' bu korumalı kod alanına verilen addır. Paylaşılan kaynakları kullanmadan önce belli bir alanda birçok kurulum gerçekleştiriyoruz ve bunları kullanmayı bitirdikten sonra kilitlerini bir kez daha açıyoruz.

C'de çoklu iş parçacığında kilitleme ve kilit açma için muteksin çalışmasını inceleyelim:

Örnek:

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

Açıklama:

window.open javascript

Yukarıdaki örnekte, nasıl yaptığımızı açıklıyoruz. kilit Ve Kilidini aç Bizi yarış durumundan koruyan belirli bir kod bölgesi. 'pthread_mutex_t' olarak kullanılır başlatıcı yukarıdaki örnekte. 'pthread_mutex_lock' o zaman yazılı kilitlemek istediğimiz kodun başlangıcından önce. Bundan sonra kilitlemek istediğimiz kodlama bitmiştir. Bundan sonra kodun kilitlenmesi kullanılarak sonlandırılır. 'pthread_mutex_unlock' ; bundan sonra hiçbir kod kilit modunda olmayacak.

Yemek Filozofunun Sorunu:

Senkronizasyonla ilgili klasik sorunlardan biri yemek felsefecisi sorunu . Çeşitli işlemler için basit kaynak tahsisi gereklidir ancak çıkmaz veya açlık . yemek felsefecisi sorunu her biri kaynak gerektiren bir dizi sürecin basit bir temsili olarak görülebilir. Bu süreçlerin her biri bir kaynak tahsisi gerektirdiğinden, hiçbir sürecin takılıp kalmaması veya çalışmayı durdurmaması için bu kaynakların tüm süreçlere dağıtılması gerekir.

Bir masada beş filozofun oturduğunu varsayalım. daire şeklinde masa . Bir noktada yemek yiyorlar, diğerinde ise bir şeyler düşünüyorlar. Yuvarlak masanın etrafındaki filozoflar sandalyelere eşit aralıklarla yerleştirilmişlerdir. Ayrıca masanın ortasında her filozof için bir kase pirinç ve beş adet yemek çubuğu bulunmaktadır. Filozof yakınlarda oturan meslektaşlarıyla etkileşime giremeyeceğini hissettiğinde.

Bir filozof ara sıra acıktığında eline iki yemek çubuğu alır. Komşularından iki yemek çubuğu seçiyor; biri kendisinde sol ve bir tanesi onun üzerinde Sağ -kolayca ulaşılabilecek yerlerde. Ancak filozof asla aynı anda birden fazla yemek çubuğunu eline almamalıdır. Belli ki komşunun kullandığı yemek çubuğunu alamayacak.

Örnek:

Bunun C'de nasıl uygulandığını göstermek için bir örnek kullanalım.

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

Açıklama:

Yemek çubukları bir semaforla temsil edilebilir. Orada olduğundan yemek çubukları masanın üzerinde ve hiçbir filozof bunlardan birini seçmemişse, yemek çubuklarının tüm bileşenleri ilk olarak başlatılır. 1 . Şimdi yemek çubuğu[i] ilk olarak seçildi çubuk. yemek çubuğu[i] Ve yemek çubuğu[(i+1)%5] ilk bekleme işlemine tabi tutulur. Bunlar yemek çubuklarının bekleme işlemi filozofun onları topladığını gösterir. Filozof yemeğini seçtiğinde yeme süreci başlar. çubuk . Sinyal işlemi artık yemek çubukları [i] Ve [(i+1)%5] Filozof yemeğini bitirdikten sonra. Filozof daha sonra tekrar uykuya döner.

olup olmadığını belirlemek için alt konu ana konuya katılıp katılmadığını biz kullandık pthread_join işlevi . Benzer şekilde, olup olmadığını da kontrol ettik. muteks kilit kullanılarak başlatıldı pthread_mutex_init yöntem.

Yeni iş parçacığının oluşturulup oluşturulmadığını başlatmak ve doğrulamak için şunu kullandık: pthread_create işlevi . Buna benzer şekilde yok ettik. muteks kilidi kullanmak pthread_mutex_destroy işlev.

Üretici-Tüketici Sorunu:

Çok iş parçacıklı işlem senkronizasyonunda sık karşılaşılan bir sorun, üretici-tüketici sorunu . İçinde iki süreç mevcuttur: Birincisi yapımcı süreci ve ikincisi ise tüketici süreci . Ayrıca her iki işlemin de eş zamanlı ve paralel olarak gerçekleştiği varsayılmaktadır. Ek olarak, bunlar işbirliğine dayalı bir süreçtir, yani birbirleriyle bir şeyler paylaştıklarını ima eder. Tamponun ne zaman olması önemlidir tam dolu üretici veri ekleyemez. Arabellek boş olduğunda, üretici ile tüketici arasındaki ortak arabellek boyutu olduğundan tüketici arabellekten veri çıkaramaz. sabit . Konu bu şekilde ifade ediliyor. Dolayısıyla Üretici-Tüketici problemini uygulamak ve çözmek için paralel programlama fikrini kullanacağız.

Örnek:

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

Çıktı:

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

Açıklama:

bağlantı kur

İki görevi gerçekleştiriyoruz. Fonksiyonlar tüketici() Ve üretici() durumunu ve çalışmasını belirtin tüketici Ve üretici . yapımcı() yöntemi yaratacak muteks kilidi ve tamponun olup olmadığını belirleyin tam dolu çağrıldığında. Tampon dolduğunda hiçbir şey üretilmeyecektir. Değilse, olacak yaratmak ve ardından, üretme kilidini açmak için kendini uyku moduna geçirecektir. muteks kilidi . Gibi üretici tüketici ilk önce onu yaratır muteks kilidi , kontrol eder tampon , tüketir ürün ve tekrar uykuya geçmeden önce kilidi serbest bırakır.

A sayaç (x) Üretim sırasında kullanılacak ve üretici ürünü üretene kadar büyümeye devam edecek. Ancak tüketici aynı üretilen üründen daha azını üretecek öğe (x) .

Çözüm:

Kullanma fikri iki veya daha fazla konu bir programı yürütmek olarak bilinir çoklu iş parçacığı C programlama dilinde. Çoklu iş parçacığı birden fazla görevin aynı anda yürütülmesine olanak sağlar. Bir programın en basit yürütülebilir bileşeni, iplik . Süreç, bir görevin birkaç küçük parçaya bölünerek tamamlanabileceği fikridir. alt süreçler .

Başlık dosyası pthread.h Doğrudan yapılamadığı için C'de çoklu iş parçacığı uygulamak için gereklidir.