Concurrence en Python - Threads

En général, comme nous le savons, le fil est une ficelle torsadée très fine généralement du tissu de coton ou de soie et utilisée pour coudre des vêtements et autres. Le même terme fil est également utilisé dans le monde de la programmation informatique. Maintenant, comment relier le fil utilisé pour coudre les vêtements et le fil utilisé pour la programmation informatique? Les rôles joués par les deux threads sont similaires ici. Dans les vêtements, le fil tient le tissu ensemble et de l'autre côté, dans la programmation informatique, le fil tient le programme informatique et permet au programme d'exécuter des actions séquentielles ou de nombreuses actions à la fois.

Threadest la plus petite unité d'exécution dans un système d'exploitation. Ce n'est pas en soi un programme mais s'exécute dans un programme. En d'autres termes, les threads ne sont pas indépendants les uns des autres et partagent une section de code, une section de données, etc. avec d'autres threads. Ces threads sont également appelés processus légers.

États du fil

Pour comprendre en profondeur la fonctionnalité des threads, nous devons en savoir plus sur le cycle de vie des threads ou sur les différents états des threads. En règle générale, un thread peut exister dans cinq états distincts. Les différents états sont indiqués ci-dessous -

Nouveau fil

Un nouveau thread commence son cycle de vie dans le nouvel état. Cependant, à ce stade, il n'a pas encore démarré et aucune ressource ne lui a été allouée. Nous pouvons dire que ce n'est qu'une instance d'un objet.

Runnable

Lorsque le thread nouvellement né est démarré, le thread devient exécutable, c'est-à-dire en attente d'exécution. Dans cet état, il dispose de toutes les ressources mais le planificateur de tâches n'a toujours pas planifié son exécution.

Fonctionnement

Dans cet état, le thread progresse et exécute la tâche, qui a été choisie par le planificateur de tâches à exécuter. Maintenant, le thread peut passer soit à l'état mort, soit à l'état non exécutable / en attente.

Non en cours d'exécution / en attente

Dans cet état, le thread est suspendu car il attend la réponse d'une demande d'E / S ou attend la fin de l'exécution d'un autre thread.

Mort

Un thread exécutable entre dans l'état terminé lorsqu'il termine sa tâche ou s'arrête autrement.

Le diagramme suivant montre le cycle de vie complet d'un thread -

Types de fil

Dans cette section, nous verrons les différents types de threads. Les types sont décrits ci-dessous -

Threads de niveau utilisateur

Ce sont des threads gérés par l'utilisateur.

Dans ce cas, le noyau de gestion des threads n'a pas connaissance de l'existence de threads. La bibliothèque de threads contient du code pour créer et détruire des threads, pour passer des messages et des données entre des threads, pour planifier l'exécution de threads et pour enregistrer et restaurer des contextes de thread. L'application démarre avec un seul thread.

Les exemples de threads de niveau utilisateur sont -

  • Fils Java
  • Fils POSIX

Avantages des threads de niveau utilisateur

Voici les différents avantages des threads de niveau utilisateur -

  • La commutation de thread ne nécessite pas de privilèges de mode noyau.
  • Le thread de niveau utilisateur peut s'exécuter sur n'importe quel système d'exploitation.
  • La planification peut être spécifique à l'application dans le thread de niveau utilisateur.
  • Les threads de niveau utilisateur sont rapides à créer et à gérer.

Inconvénients des threads de niveau utilisateur

Voici les différents inconvénients des threads de niveau utilisateur -

  • Dans un système d'exploitation classique, la plupart des appels système sont bloquants.
  • L'application multithread ne peut pas tirer parti du multitraitement.

Threads au niveau du noyau

Les threads gérés par le système d'exploitation agissent sur le noyau, qui est un noyau du système d'exploitation.

Dans ce cas, le noyau fait la gestion des threads. Il n'y a pas de code de gestion des threads dans la zone d'application. Les threads du noyau sont pris en charge directement par le système d'exploitation. Toute application peut être programmée pour être multithread. Tous les threads d'une application sont pris en charge dans un seul processus.

Le noyau conserve les informations de contexte pour le processus dans son ensemble et pour les threads individuels du processus. La planification par le noyau se fait sur une base de thread. Le noyau effectue la création, la planification et la gestion des threads dans l'espace noyau. Les threads du noyau sont généralement plus lents à créer et à gérer que les threads utilisateur. Les exemples de threads au niveau du noyau sont Windows, Solaris.

Avantages des threads au niveau du noyau

Voici les différents avantages des threads au niveau du noyau -

  • Le noyau peut planifier simultanément plusieurs threads du même processus sur plusieurs processus.

  • Si un thread d'un processus est bloqué, le noyau peut planifier un autre thread du même processus.

  • Les routines du noyau elles-mêmes peuvent être multithreads.

Inconvénients des threads au niveau du noyau

  • Les threads du noyau sont généralement plus lents à créer et à gérer que les threads utilisateur.

  • Le transfert de contrôle d'un thread à un autre au sein du même processus nécessite un changement de mode vers le noyau.

Bloc de contrôle de filetage - TCB

Le bloc de contrôle des threads (TCB) peut être défini comme la structure de données du noyau du système d'exploitation qui contient principalement des informations sur les threads. Les informations spécifiques aux threads stockées dans TCB mettront en évidence certaines informations importantes sur chaque processus.

Considérez les points suivants liés aux threads contenus dans TCB -

  • Thread identification - C'est l'identifiant de thread unique (tid) attribué à chaque nouveau thread.

  • Thread state - Il contient les informations relatives à l'état (Running, Runnable, Non-Running, Dead) du thread.

  • Program Counter (PC) - Il pointe vers l'instruction de programme actuelle du thread.

  • Register set - Il contient les valeurs de registre du thread qui leur sont assignées pour les calculs.

  • Stack Pointer- Il pointe vers la pile du thread dans le processus. Il contient les variables locales sous la portée du thread.

  • Pointer to PCB - Il contient le pointeur vers le processus qui a créé ce thread.

Relation entre processus et thread

En multithreading, processus et thread sont deux termes très étroitement liés ayant le même objectif de rendre l'ordinateur capable de faire plus d'une chose à la fois. Un processus peut contenir un ou plusieurs threads mais au contraire, un thread ne peut pas contenir de processus. Cependant, ils restent tous les deux les deux unités de base de l'exécution. Un programme, exécutant une série d'instructions, lance le processus et le thread à la fois.

Le tableau suivant montre la comparaison entre processus et thread -

Processus Fil
Le processus est lourd ou gourmand en ressources. Thread est léger et prend moins de ressources qu'un processus.
La commutation de processus nécessite une interaction avec le système d'exploitation. La commutation de thread n'a pas besoin d'interagir avec le système d'exploitation.
Dans plusieurs environnements de traitement, chaque processus exécute le même code mais possède sa propre mémoire et ses propres ressources de fichiers. Tous les threads peuvent partager le même ensemble de fichiers ouverts, processus enfants.
Si un processus est bloqué, aucun autre processus ne peut s'exécuter tant que le premier processus n'est pas débloqué. Pendant qu'un thread est bloqué et en attente, un deuxième thread de la même tâche peut s'exécuter.
Plusieurs processus sans utiliser de threads utilisent plus de ressources. Plusieurs processus threadés utilisent moins de ressources.
Dans plusieurs processus, chaque processus fonctionne indépendamment des autres. Un thread peut lire, écrire ou modifier les données d'un autre thread.
S'il y avait un changement dans le processus parent, cela n'affecte pas les processus enfants. S'il y avait une modification dans le thread principal, cela peut affecter le comportement des autres threads de ce processus.
Pour communiquer avec des processus frères, les processus doivent utiliser la communication inter-processus. Les threads peuvent communiquer directement avec d'autres threads de ce processus.

Concept de multithreading

Comme nous l'avons vu précédemment, le multithreading est la capacité d'un processeur à gérer l'utilisation du système d'exploitation en exécutant plusieurs threads simultanément. L'idée principale du multithreading est de réaliser le parallélisme en divisant un processus en plusieurs threads. De manière plus simple, on peut dire que le multithreading est le moyen de réaliser le multitâche en utilisant le concept de threads.

Le concept de multithreading peut être compris à l'aide de l'exemple suivant.

Exemple

Supposons que nous exécutions un processus. Le processus pourrait être d'ouvrir MS Word pour écrire quelque chose. Dans un tel processus, un thread sera assigné pour ouvrir MS word et un autre thread sera nécessaire pour écrire. Maintenant, supposons que si nous voulons éditer quelque chose, un autre thread sera nécessaire pour effectuer la tâche d'édition et ainsi de suite.

Le diagramme suivant nous aide à comprendre comment plusieurs threads existent en mémoire -

Nous pouvons voir dans le diagramme ci-dessus que plusieurs threads peuvent exister dans un processus où chaque thread contient son propre jeu de registres et des variables locales. En dehors de cela, tous les threads d'un processus partagent des variables globales.

Avantages du multithreading

Voyons maintenant quelques avantages du multithreading. Les avantages sont les suivants -

  • Speed of communication - Le multithreading améliore la vitesse de calcul car chaque cœur ou processeur gère des threads séparés simultanément.

  • Program remains responsive - Il permet à un programme de rester réactif car un thread attend l'entrée et un autre exécute une interface graphique en même temps.

  • Access to global variables - En multithreading, tous les threads d'un processus particulier peuvent accéder aux variables globales et s'il y a un changement dans la variable globale, il est également visible pour les autres threads.

  • Utilization of resources - L'exécution de plusieurs threads dans chaque programme permet une meilleure utilisation du processeur et le temps d'inactivité du processeur diminue.

  • Sharing of data - Il n'y a pas besoin d'espace supplémentaire pour chaque thread car les threads d'un programme peuvent partager les mêmes données.

Inconvénients du multithreading

Voyons maintenant quelques inconvénients du multithreading. Les inconvénients sont les suivants -

  • Not suitable for single processor system - Le multithreading a du mal à obtenir des performances en termes de vitesse de calcul sur un système à processeur unique par rapport aux performances sur un système multiprocesseur.

  • Issue of security - Comme nous savons que tous les threads d'un programme partagent les mêmes données, il y a donc toujours un problème de sécurité car tout thread inconnu peut changer les données.

  • Increase in complexity - Le multithreading peut augmenter la complexité du programme et le débogage devient difficile.

  • Lead to deadlock state - Le multithreading peut conduire le programme à un risque potentiel d'atteindre l'état de blocage.

  • Synchronization required- La synchronisation est nécessaire pour éviter l'exclusion mutuelle. Cela conduit à une plus grande utilisation de la mémoire et du processeur.