Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Industrial programming >> C Taal

C++ Multithreading

Multithreading is een gespecialiseerde vorm van multitasking en multitasking is de functie waarmee uw computer twee of meer programma's tegelijk kan uitvoeren. Over het algemeen zijn er twee soorten multitasking:procesgebaseerd en threadgebaseerd.

Procesgebaseerde multitasking zorgt voor de gelijktijdige uitvoering van programma's. Op threads gebaseerde multitasking houdt zich bezig met de gelijktijdige uitvoering van delen van hetzelfde programma.

Een programma met meerdere threads bevat twee of meer delen die gelijktijdig kunnen worden uitgevoerd. Elk deel van zo'n programma wordt een thread genoemd en elke thread definieert een afzonderlijk uitvoeringspad.

C++ bevat geen ingebouwde ondersteuning voor toepassingen met meerdere threads. In plaats daarvan vertrouwt het volledig op het besturingssysteem om deze functie te bieden.

Deze tutorial gaat ervan uit dat je werkt met Linux OS en we gaan een multi-threaded C++ programma schrijven met POSIX. POSIX Threads of Pthreads biedt API die beschikbaar is op veel Unix-achtige POSIX-systemen zoals FreeBSD, NetBSD, GNU/Linux, Mac OS X en Solaris.

Draden maken

De volgende routine wordt gebruikt om een ​​POSIX-thread te maken −

#include <pthread.h>
pthread_create (thread, attr, start_routine, arg) 

Hier, pthread_create maakt een nieuwe thread aan en maakt deze uitvoerbaar. Deze routine kan een willekeurig aantal keren worden aangeroepen vanaf elke plek in uw code. Hier is de beschrijving van de parameters −

Zr.Nee Parameter en beschrijving
1

draad

Een ondoorzichtige, unieke identifier voor de nieuwe thread die wordt geretourneerd door de subroutine.

2

attr

Een ondoorzichtig attribuutobject dat kan worden gebruikt om threadattributen in te stellen. U kunt een thread-attribuutobject specificeren, of NULL voor de standaardwaarden.

3

start_routine

De C++-routine die de thread zal uitvoeren zodra deze is gemaakt.

4

arg

Een enkel argument dat kan worden doorgegeven aan start_routine. Het moet door verwijzing worden doorgegeven als een pointer cast van het type void. NULL kan worden gebruikt als er geen argument moet worden doorgegeven.

Het maximale aantal threads dat door een proces kan worden gemaakt, is afhankelijk van de implementatie. Eenmaal gemaakt, zijn threads peers en kunnen andere threads worden gemaakt. Er is geen impliciete hiërarchie of afhankelijkheid tussen threads.

Threads beëindigen

Er is de volgende routine die we gebruiken om een ​​POSIX-thread te beëindigen −

#include <pthread.h>
pthread_exit (status) 

Hier pthread_exit wordt gebruikt om een ​​thread expliciet te verlaten. Gewoonlijk wordt de routine pthread_exit() aangeroepen nadat een thread zijn werk heeft voltooid en hoeft deze niet langer te bestaan.

Als main() eindigt voor de threads die het heeft gemaakt, en afsluit met pthread_exit(), zullen de andere threads doorgaan met uitvoeren. Anders worden ze automatisch beëindigd wanneer main() klaar is.

Voorbeeld

Deze eenvoudige voorbeeldcode maakt 5 threads aan met de routine pthread_create(). Elke draad drukt een "Hello World!" bericht, en wordt dan beëindigd met een aanroep van pthread_exit().

#include <iostream>
#include <cstdlib>
#include <pthread.h>

using namespace std;

#define NUM_THREADS 5

void *PrintHello(void *threadid) {
   long tid;
   tid = (long)threadid;
   cout << "Hello World! Thread ID, " << tid << endl;
   pthread_exit(NULL);
}

int main () {
   pthread_t threads[NUM_THREADS];
   int rc;
   int i;
   
   for( i = 0; i < NUM_THREADS; i++ ) {
      cout << "main() : creating thread, " << i << endl;
      rc = pthread_create(&threads[i], NULL, PrintHello, (void *)i);
      
      if (rc) {
         cout << "Error:unable to create thread," << rc << endl;
         exit(-1);
      }
   }
   pthread_exit(NULL);
}

Compileer het volgende programma met de bibliotheek -lpthread als volgt −

$gcc test.cpp -lpthread

Voer nu uw programma uit dat de volgende uitvoer geeft −

main() : creating thread, 0
main() : creating thread, 1
main() : creating thread, 2
main() : creating thread, 3
main() : creating thread, 4
Hello World! Thread ID, 0
Hello World! Thread ID, 1
Hello World! Thread ID, 2
Hello World! Thread ID, 3
Hello World! Thread ID, 4

Argumenten doorgeven aan discussielijnen

Dit voorbeeld laat zien hoe u meerdere argumenten via een structuur kunt doorgeven. U kunt elk gegevenstype in een thread-callback doorgeven omdat het naar void verwijst, zoals uitgelegd in het volgende voorbeeld −

#include <iostream>
#include <cstdlib>
#include <pthread.h>

using namespace std;

#define NUM_THREADS 5

struct thread_data {
   int  thread_id;
   char *message;
};

void *PrintHello(void *threadarg) {
   struct thread_data *my_data;
   my_data = (struct thread_data *) threadarg;

   cout << "Thread ID : " << my_data->thread_id ;
   cout << " Message : " << my_data->message << endl;

   pthread_exit(NULL);
}

int main () {
   pthread_t threads[NUM_THREADS];
   struct thread_data td[NUM_THREADS];
   int rc;
   int i;

   for( i = 0; i < NUM_THREADS; i++ ) {
      cout <<"main() : creating thread, " << i << endl;
      td[i].thread_id = i;
      td[i].message = "This is message";
      rc = pthread_create(&threads[i], NULL, PrintHello, (void *)&td[i]);
      
      if (rc) {
         cout << "Error:unable to create thread," << rc << endl;
         exit(-1);
      }
   }
   pthread_exit(NULL);
}

Wanneer de bovenstaande code wordt gecompileerd en uitgevoerd, levert dit het volgende resultaat op −

main() : creating thread, 0
main() : creating thread, 1
main() : creating thread, 2
main() : creating thread, 3
main() : creating thread, 4
Thread ID : 3 Message : This is message
Thread ID : 2 Message : This is message
Thread ID : 0 Message : This is message
Thread ID : 1 Message : This is message
Thread ID : 4 Message : This is message

Draden samenvoegen en losmaken

Er zijn de volgende twee routines die we kunnen gebruiken om threads samen te voegen of los te koppelen −

pthread_join (threadid, status) 
pthread_detach (threadid) 

De subroutine pthread_join() blokkeert de aanroepende thread totdat de opgegeven 'threadid'-thread wordt beëindigd. Wanneer een thread wordt gemaakt, bepaalt een van de attributen of deze koppelbaar of losgekoppeld is. Alleen threads die als koppelbaar zijn gemaakt, kunnen worden samengevoegd. Als een thread als losgemaakt is gemaakt, kan er nooit aan worden toegevoegd.

Dit voorbeeld laat zien hoe te wachten op het voltooien van een thread met behulp van de Pthread-deelnameroutine.

#include <iostream>
#include <cstdlib>
#include <pthread.h>
#include <unistd.h>

using namespace std;

#define NUM_THREADS 5

void *wait(void *t) {
   int i;
   long tid;

   tid = (long)t;

   sleep(1);
   cout << "Sleeping in thread " << endl;
   cout << "Thread with id : " << tid << "  ...exiting " << endl;
   pthread_exit(NULL);
}

int main () {
   int rc;
   int i;
   pthread_t threads[NUM_THREADS];
   pthread_attr_t attr;
   void *status;

   // Initialize and set thread joinable
   pthread_attr_init(&attr);
   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

   for( i = 0; i < NUM_THREADS; i++ ) {
      cout << "main() : creating thread, " << i << endl;
      rc = pthread_create(&threads[i], &attr, wait, (void *)i );
      if (rc) {
         cout << "Error:unable to create thread," << rc << endl;
         exit(-1);
      }
   }

   // free attribute and wait for the other threads
   pthread_attr_destroy(&attr);
   for( i = 0; i < NUM_THREADS; i++ ) {
      rc = pthread_join(threads[i], &status);
      if (rc) {
         cout << "Error:unable to join," << rc << endl;
         exit(-1);
      }
      cout << "Main: completed thread id :" << i ;
      cout << "  exiting with status :" << status << endl;
   }

   cout << "Main: program exiting." << endl;
   pthread_exit(NULL);
}

Wanneer de bovenstaande code wordt gecompileerd en uitgevoerd, levert dit het volgende resultaat op −

main() : creating thread, 0
main() : creating thread, 1
main() : creating thread, 2
main() : creating thread, 3
main() : creating thread, 4
Sleeping in thread
Thread with id : 0 .... exiting
Sleeping in thread
Thread with id : 1 .... exiting
Sleeping in thread
Thread with id : 2 .... exiting
Sleeping in thread
Thread with id : 3 .... exiting
Sleeping in thread
Thread with id : 4 .... exiting
Main: completed thread id :0  exiting with status :0
Main: completed thread id :1  exiting with status :0
Main: completed thread id :2  exiting with status :0
Main: completed thread id :3  exiting with status :0
Main: completed thread id :4  exiting with status :0
Main: program exiting.

C Taal

  1. C++-operators
  2. C++ Opmerkingen
  3. C++-klassesjablonen
  4. C++-overzicht
  5. C++-constanten/letters
  6. Operatoren in C++
  7. Getallen in C++
  8. C++-referenties
  9. C++-sjablonen
  10. C++ Multithreading
  11. C# - Multithreading