Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Industrial programming >> Langue C

Multithreading C++

Le multithreading est une forme spécialisée de multitâche et un multitâche est la fonctionnalité qui permet à votre ordinateur d'exécuter deux programmes ou plus simultanément. En général, il existe deux types de multitâche :basé sur les processus et basé sur les threads.

Le multitâche basé sur les processus gère l'exécution simultanée de programmes. Le multitâche basé sur les threads traite de l'exécution simultanée de parties du même programme.

Un programme multithread contient deux parties ou plus qui peuvent s'exécuter simultanément. Chaque partie d'un tel programme est appelée un thread, et chaque thread définit un chemin d'exécution séparé.

C++ ne contient aucun support intégré pour les applications multithread. Au lieu de cela, il s'appuie entièrement sur le système d'exploitation pour fournir cette fonctionnalité.

Ce didacticiel suppose que vous travaillez sur le système d'exploitation Linux et que nous allons écrire un programme C++ multithread en utilisant POSIX. Les threads POSIX, ou Pthreads, fournissent des API disponibles sur de nombreux systèmes POSIX de type Unix tels que FreeBSD, NetBSD, GNU/Linux, Mac OS X et Solaris.

Créer des sujets

La routine suivante est utilisée pour créer un thread POSIX −

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

Ici, pthread_create crée un nouveau thread et le rend exécutable. Cette routine peut être appelée n'importe quel nombre de fois depuis n'importe où dans votre code. Voici la description des paramètres −

fil

Un identifiant opaque et unique pour le nouveau thread renvoyé par la sous-routine.

attr

Un objet d'attribut opaque qui peut être utilisé pour définir des attributs de thread. Vous pouvez spécifier un objet d'attributs de thread, ou NULL pour les valeurs par défaut.

démarrer_routine

La routine C++ que le thread exécutera une fois créé.

argument

Un seul argument qui peut être passé à start_routine. Il doit être passé par référence en tant que transtypage de pointeur de type void. NULL peut être utilisé si aucun argument ne doit être passé.

Sr.No Paramètre et description
1
2
3
4

Le nombre maximal de threads pouvant être créés par un processus dépend de l'implémentation. Une fois créés, les threads sont pairs et peuvent créer d'autres threads. Il n'y a pas de hiérarchie ou de dépendance implicite entre les threads.

Terminer les threads

Il y a la routine suivante que nous utilisons pour terminer un thread POSIX −

#include <pthread.h>
pthread_exit (status) 

Ici pthread_exit est utilisé pour quitter explicitement un thread. En règle générale, la routine pthread_exit() est appelée après qu'un thread a terminé son travail et qu'il n'est plus nécessaire d'exister.

Si main() se termine avant les threads qu'il a créés et se termine avec pthread_exit(), les autres threads continueront à s'exécuter. Sinon, ils seront automatiquement terminés lorsque main() se terminera.

Exemple

Cet exemple de code simple crée 5 threads avec la routine pthread_create(). Chaque thread imprime un "Hello World!" message, puis se termine par un appel à 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);
}

Compilez le programme suivant en utilisant la bibliothèque -lpthread comme suit −

$gcc test.cpp -lpthread

Maintenant, exécutez votre programme qui donne la sortie suivante −

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

Passer des arguments aux threads

Cet exemple montre comment passer plusieurs arguments via une structure. Vous pouvez passer n'importe quel type de données dans un rappel de thread car il pointe vers void comme expliqué dans l'exemple suivant −

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

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant −

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

Joindre et détacher des fils

Il existe deux routines suivantes que nous pouvons utiliser pour joindre ou détacher des threads −

pthread_join (threadid, status) 
pthread_detach (threadid) 

La sous-routine pthread_join() bloque le thread appelant jusqu'à ce que le thread 'threadid' spécifié se termine. Lorsqu'un thread est créé, l'un de ses attributs définit s'il est joignable ou détaché. Seuls les threads créés comme joignables peuvent être joints. Si un fil est créé comme détaché, il ne peut jamais être joint.

Cet exemple montre comment attendre la fin des threads à l'aide de la routine de jointure Pthread.

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

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant −

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.

Langue C

  1. Opérateurs C++
  2. Commentaires C++
  3. Modèles de classe C++
  4. Présentation de C++
  5. Constantes/littéraux C++
  6. Opérateurs en C++
  7. Les nombres en C++
  8. Références C++
  9. Modèles C++