logo

MULTITREADING I C

Introduktion:

I C, udtrykket 'multithreading' beskriver brugen af ​​talrige tråde samtidig. Hver tråd gør en anderledes opgave . På grund af den samtidige karakter af multithreading kan mange opgaver udføres på én gang. Derudover multithreading reducerer CPU's ressourceforbrug . Der er to kategorier af multitasking: procesbaseret og trådbaseret . Når noget beskrives som multithreading, betyder det, at mindst to eller måske flere tråde kører i samme proces på én gang. Vi skal først forstå, hvad en tråd og en proces er for at forstå multithreading i C. Lad os se på disse emner for at få en bedre forståelse.

til streng metode java

Hvad er processer og tråde?

EN tråd er grundlæggende bygning blok af enhver process udførelse. Et program er opbygget af flere processer, og hver proces er opbygget af tråde, som er meget mere grundlæggende enheder. Derfor kan tråden betragtes som den grundlæggende byggesten i en proces eller den enklere enhed, der i fællesskab bestemmer CPU-udnyttelsen.

Følgende elementer er inkluderet i en tråd:

Tråd ID:

Det er en speciel tråd ID der genereres på tidspunktet for tråddannelsen og bevares i den specifikke tråds varighed.

Programtæller:

Det er en værdi, som hardware belastninger .

Et registreret sæt:

Det er en samling af fælles registre .

En stak:

Det er en rest af det specifik tråd .

Derudover, hvis to tråde arbejder samtidigt i den samme proces, deler de kode , datasektioner , og andre operativsystemressourcer som fil åbner og signaler . En sværvægtsproces, en type konventionel proces, kan styre én tråd. Imidlertid har en multi-thread of control kapacitet til at åbne og udføre flere opgaver samtidigt. Systemet bliver betydeligt mere effektivt ved at bruge tråde, hvorfor de er nyttige.

Forskellen mellem enkelt og multithreading i C er forklaret. Først og fremmest er det en enkelt-trådet proces . Som et resultat, hele blokken, herunder kode, data, osv. - betragtes som én proces, og den proces har kun én tråd. Det betyder, at denne teknik kun vil fuldføre én opgave ad gangen. Men der er en multithreading proces der står i modsætning hertil. Der er aktiviteter som kode, stak, data , og filer også, men de udføres af flere tråde, som hver har sin egen stak og registre. I betragtning af at mange opgaver kan udføres på én gang i denne situation, er processen kendt som en multithreading proces .

Tråd findes i to varianter:

Tråd på brugerniveau:

Det er på brugerniveau, som navnet antyder. Kernen får ikke adgang til dens data.

Tråd på kerneniveau

Den slags tråd refererer til trådens forhold til kernen og systemets operativsystem.

Behandle- Rækken af ​​trin, der er taget for at gennemføre et program, kan omtales som behandle . Et program køres ikke med det samme, når det køres. Det er opdelt i nogle få grundlæggende trin, der udføres sekventielt på en organiseret måde for til sidst at føre til udførelse af en proces.

En proces, der er blevet opdelt i mindre trin, kaldes en 'klone- eller børneproces', mens den oprindelige proces omtales som 'forældreproces' . I hukommelsen bruger hver proces en vis mængde plads, som ikke deles med andre processer.

En procedure gennemgår nogle stadier forud for udførelse.

NY-

I denne situation er en ny proces genereret .

PARAT-

Når en proces er forberedt og venter på, at en processor bliver tildelt, er den i denne tilstand.

LØB-

Når processen er aktiv, er det staten.

hvad gør en pc hurtig

VENTER-

Når en proces er i denne tilstand, er der noget venter at ske.

AFSLUTTE-

Det er den tilstand, hvori proceduren udføres.

Hvorfor er C multitrådet?

Multithreading i C-ideen kan udnyttes gennem parallelisme til at forbedre en applikationens funktionalitet . Overvej det tilfælde, hvor du har flere faner åbne i et browservindue. Derefter fungerer hver fane samtidigt og kan blive omtalt som en Tråd . Forudsat at vi bruger Microsoft Excel , vil én tråd klare sig tekstformatering , og en tråd vil håndtere input . Derfor gør C's multithreading-funktion det nemt at udføre flere opgaver på én gang. Oprettelse af en tråd er betydeligt hurtigere. Kontekstoverførslen på tværs af tråde sker hurtigere. Derudover kan kommunikation mellem tråde udføres hurtigere, og trådterminering er enkel.

Hvordan skriver man C-programmer til multithreading?

Selvom multithreading-applikationer ikke er indbygget i C-sproget, er det muligt afhængigt af operativsystemet. Det threads.h standardbibliotek bruges til at implementere multithreading idéen i C . Der er dog i øjeblikket ingen compiler, der kan gøre dette. Vi skal anvende platformspecifikke implementeringer, såsom 'POSIX' tråde-biblioteket ved at bruge header-filen pthread.h , hvis vi vil bruge multithreading i C. 'Pthreads' er et andet navn for dette. EN POSIX tråd kan oprettes på følgende måder:

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

I dette tilfælde, Pthread_create opretter en ny tråd for at gøre tråden eksekverbar. Det giver dig mulighed for at implementere multithreading i C så mange gange du vil i din kode. Parametrene og deres beskrivelser fra tidligere er listet her.

tråd:

Det er en ental identifikation at delproces returnerer .

attr:

Når vi vil indstille trådattributter, bruger vi dette uigennemsigtig egenskab .

start_rutine:

Hvornår start_rutine er genereret, vil tråden køre en rutine.

arg:

Den parameter, som start_rutine modtager. NUL vil blive brugt, hvis der ikke er givet argumenter.

softwaretest og typer

Visse C multithreading eksempler

Her er nogle eksempler på multithreading-problemer i C.

1. Læser-forfatter-udgaven

Et almindeligt operativsystemproblem med processynkronisering er læser/skribent problem . Antag, at vi har en database, der Læsere og Forfattere , to forskellige brugerkategorier, kan få adgang til. Læsere er de eneste der kan Læs databasen, hvorimod Forfattere er de eneste, der kan læse databasen og også opdatere den. Lad os bruge IRCTC som et simpelt eksempel. Hvis vi ønsker at kontrollere status for en bestemt tognummer , skal du blot indtaste tognummeret i systemet for at se de relevante togoplysninger. Kun den information, der er til stede på hjemmesiden, vises her. Læseoperatoren er denne. Men hvis vi ønsker at reservere en billet, skal vi udfylde billetbestillingsformularen med detaljer som vores navn, alder og så videre. Så vi udfører en skriveoperation her. Der vil blive foretaget nogle justeringer af IRCTC database .

Problemet er, at flere personer samtidig forsøger at få adgang til IRCTC database . De kan være en forfatter eller a læser . Problemet opstår, hvis en læser allerede bruger databasen, og en forfatter får adgang til den samtidigt for at arbejde på de samme data. Et andet problem opstår, når en forfatter bruger en database, og en læser får adgang til de samme oplysninger som databasen. For det tredje er der et problem, når en forfatter opdaterer databasen, mens en anden forsøger at opdatere data på den samme database. Det fjerde scenarie opstår, når to læsere forsøger at hente det samme materiale. Alle disse problemer opstår, hvis læseren og forfatteren bruger de samme databasedata.

Semafor er en metode, der bruges til at løse dette problem. Lad os se på en illustration af, hvordan du bruger dette problem.

Læserproces:

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

Forklaring:

I denne kode har vi de delte variable data og læserantal rc . Det wrt stand variabel bruges til at begrænse adgangen til forfatterproces , og mutex bruges til at garantere gensidig udelukkelse for adgang til de delte data.

Læserprocessen er repræsenteret ved reader() funktion . Det læserantal (rc) øges, før man opnår mutex lås . Det bruger pthread_cond_wait() at vente på wrt stand variabel, hvis det er første læser (rc == 1) . Som et resultat vil forfattere blive forhindret i at skrive, indtil alle læsere har afsluttet.

Læserprocessen tjekker, om det var sidste læser (rc == 0) og sænker læseren tælle (rc--) efter at have læst de delte data. Hvis det var, pthread_cond_signal() signalerer wrt stand variabel for at lade ventende forfatterprocesser fortsætte.

Bruger pthread_create() og pthread_join() funktioner , vi ny og tilslutte flere læsertråde i main() funktion . Et individuelt ID tildeles hver læsertråd til identifikationsformål.

Forfatterproces:

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

I ovenstående eksempel er det samme som læserproces , udføres en operation kendt som venteoperationen på 'wrt' når en bruger ønsker at få adgang til data eller objekt. Derefter vil den nye bruger ikke kunne få adgang til objektet. Og når brugeren er færdig med at skrive, udføres en anden signaloperation på wrt .

2. lås og lås problem:

Ideen om en mutex bruges i multithreading i C for at garantere, at der ikke vil være en race tilstand imellem tråde . Når flere tråde begynder at behandle de samme data på én gang, er denne omstændighed kendt som væddeløb . Men hvis disse omstændigheder eksisterer, skal vi. Vi bruger mutex's lock() og unlock() funktioner at sikre en bestemt sektion af kode for en specifik tråd. Sådan at en anden tråd ikke kan begynde at udføre den samme operation. Det 'kritisk sektion/region' er navnet på dette beskyttede kodeområde. Inden vi bruger de delte ressourcer, sætter vi en masse op i et bestemt område, og når vi er færdige med at bruge dem, låser vi dem op igen.

Lad os undersøge funktionen af ​​mutex til låsning og oplåsning i multithreading i C:

Eksempel:

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

Forklaring:

softwaretest og typer

I dette eksempel ovenfor forklarer vi, hvordan vi låse og låse op en bestemt koderegion, der beskytter os mod racersituationen. 'pthread_mutex_t' bruges som en initialisering i eksemplet ovenfor. 'pthread_mutex_lock' er da skrevet før begyndelsen af ​​den kode, som vi vil låse. Kodningen, som vi ønsker at låse, er færdig derefter. Herefter afsluttes låsningen af ​​koden vha 'pthread_mutex_unlock' ; fremadrettet vil ingen kode være i låst tilstand.

Spisefilosofproblemet:

Et af de klassiske problemer med synkronisering er spisefilosof-spørgsmål . Enkel ressourceallokering til flere processer er påkrævet, men bør ikke resultere i en dødvande eller sult . Det spisefilosof problem kan ses som en ligefrem repræsentation af en række processer, som hver især kræver ressourcer. Da hver af disse processer kræver en ressourceallokering, er det nødvendigt at fordele disse ressourcer på tværs af alle processerne, så ingen proces nogensinde sætter sig fast eller holder op med at fungere.

Antag, at der er fem filosoffer siddende ved en cirkelformet bord . De spiser på et tidspunkt og tænker over noget på et andet. Omkring det runde bord er filosofferne jævnt fordelt på stolene. Derudover er der en skål med ris og fem spisepinde til hver filosof midt på bordet. Når filosoffen føler, at hun ikke kan interagere med sine kolleger, der sidder i nærheden.

En filosof tager af og til to spisepinde, når hun bliver sulten. Hun vælger to spisepinde fra sine naboer - en på hende venstre og en på hende højre - der er inden for rækkevidde. Men filosoffen bør aldrig tage mere end én spisepind op på én gang. Hun vil åbenbart ikke kunne hente den spisepind, som naboen bruger.

Eksempel:

Lad os bruge et eksempel til at demonstrere, hvordan dette er implementeret i C.

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

Forklaring:

hvordan man fjerner det første tegn i excel

Spisepinde kan repræsenteres af en semafor. Da der er spisepinde på bordet og ingen filosof har valgt en, initialiseres alle spisepindenes komponenter først til 1 . Nu det spisepind[i] er valgt som den første spisepind. spisepind[i] og spisepind[(i+1)%5] er underlagt den første venteoperation. Disse spisepindes venteoperation indikerer, at filosoffen har samlet dem op. Spiseprocessen begynder, når filosoffen vælger sit spisepind . Signaloperationen udføres nu på spisepinde [i] og [(i+1)%5] når filosoffen er færdig med at spise. Filosoffen falder så i søvn igen.

For at afgøre, om undertråd har tilsluttet sig hovedtråden eller ej, brugte vi pthread_join funktion . Tilsvarende har vi kontrolleret, om mutex låsen er blevet initialiseret ved hjælp af pthread_mutex_init metode.

For at initialisere og kontrollere, om den nye tråd blev oprettet eller ej, brugte vi pthread_create funktion . I lighed med dette ødelagde vi mutex lås bruger pthread_mutex_destroy fungere.

Producent-forbrugerproblemet:

Et almindeligt problem med multithreading-processynkronisering er producent-forbruger problem . To processer er til stede i det: den første er producentens proces , og den anden er forbrugerens proces . Det antages endvidere, at begge operationer foregår parallelt. Derudover er de en samarbejdsproces, hvilket indebærer, at de deler noget med hinanden. Det er vigtigt, at når bufferen er fuld , kan producenten ikke tilføje data. Når bufferen er tom, kan forbrugeren ikke udtrække data fra bufferen, fordi den fælles bufferstørrelse mellem producent og forbruger er fast . Spørgsmålet er formuleret på denne måde. For at implementere producent-forbruger-problemet og løse det, vil vi derfor bruge ideen om parallel programmering.

Eksempel:

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

Produktion:

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

Forklaring:

Vi udfører to opgaver. Funktionerne forbruger() og producent() angive status og drift af forbruger og producent . Det producer() metode vil skabe mutex lås og afgør, om bufferen er fuld når det hedder. Når bufferen er fuld, vil der ikke blive produceret noget. Hvis ikke, vil det skab , og derefter, efter produktion , vil den sætte sig selv i dvale for at låse op mutex lås . Ligesom producent , skaber forbrugeren først mutex lås , tjekker buffer , forbruger den produkt , og frigiver derefter låsen, inden du går i dvale igen.

EN tæller (x) vil blive brugt under fremstillingen og vil fortsætte med at vokse, indtil producenten producerer varen. Forbrugeren vil dog lave færre af det samme fremstillet element (x) .

Konklusion:

Ideen med at bruge to eller flere tråde at udføre et program er kendt som multithreading i programmeringssproget C. Multithreading giver mulighed for samtidig udførelse af flere opgaver. Den enkleste eksekverbare komponent i et program er en tråd . Processen er ideen om, at en opgave kan udføres ved at dele den op i flere mindre delprocesser .

Overskriftsfilen pthread.h er påkrævet for at implementere multithreading i C, da det ikke kan gøres direkte.