Oui, j'ai lu de nombreux documents liés au système d'exploitation. Et je lis encore. Mais il semble qu’ils décrivent tous le processus et le processus de manière "abstraite", ce qui permet de nombreuses explications de haut niveau sur leur comportement et leur logique. Je me demande de quoi s'agit-il physiquement? À mon avis, ce ne sont que des "structures de données" en mémoire qui sont maintenues et utilisées par les codes du noyau pour faciliter l'exécution du programme. Par exemple, le système d’exploitation utilise some processus data structure (PCB) pour décrire les aspects du processus affecté à un programme donné, tels que sa priorité, son espace adresse, etc. Est-ce que ça va?
Normalement, lorsque vous exécutez un exécutable tel que notepad.exe, cela crée un processus unique. Ces processus peuvent générer d'autres processus, mais dans la plupart des cas, il existe un processus unique pour chaque exécutable que vous exécutez. Dans le processus, il peut y avoir beaucoup de threads. D'habitude, au début, il y a un thread, qui commence habituellement au programme "point d'entrée" qui est généralement la fonction main
. Les instructions sont exécutées une par une dans l'ordre, comme une personne qui n'a qu'une main, un fil ne peut faire qu'une chose à la fois avant de passer à la suivante.
Ce premier thread peut créer des threads supplémentaires. Chaque thread supplémentaire a son propre point d'entrée, qui est généralement défini avec une fonction. Le processus est comme un conteneur pour tous les threads qui y ont été créés.
C'est une explication assez simpliste. Je pourrais entrer plus dans les détails mais cela recouperait probablement ce que vous trouverez dans vos manuels.
EDIT: Vous remarquerez qu'il y a beaucoup de "habituellement" dans mon explication, car il y a parfois des programmes rares qui font des choses radicalement différentes.
La première chose que vous devez savoir pour comprendre la différence entre un processus et un thread est un fait que les processus ne s'exécutent pas, les threads le font.
Alors, quel est un fil? Le plus proche que je puisse avoir en expliquant qu'il s'agit d'un état d'exécution , comme dans: une combinaison de registres de CPU, de pile, de lot. Vous pouvez en voir une preuve en créant un débogueur à à n’importe quel moment . Que vois-tu? Une pile d'appels, un ensemble de registres. C'est à peu près tout. C'est le fil.
Maintenant, alors, quel est un processus. Eh bien, c'est comme une entité abstraite "conteneur" pour l'exécution de threads. En ce qui concerne OS, en première approximation, il s’agit d’une entité d’entreprise qui alloue des VM à, assigne des ressources système à (comme des descripteurs de fichiers, des sockets réseau), etc.
Comment travaillent-ils ensemble? Le système d'exploitation crée un "processus" en lui réservant des ressources et en démarrant un thread "principal". Ce fil peut alors générer plus de fils. Ce sont les fils d'un processus. Ils peuvent plus ou moins partager ces ressources d’une manière ou d’une autre (par exemple, un verrouillage peut être nécessaire pour ne pas gâcher le plaisir des autres, etc.). A partir de là, le système d'exploitation est normalement responsable du maintien de ces threads "à l'intérieur" de VM (détecter et empêcher les tentatives d'accès à de la mémoire qui n'appartient pas à ce processus), en fournissant un type de planification de ces threads, qu'ils peuvent courir "l'un après l'autre et pas seulement, un tout le temps".
L'une des raisons pour lesquelles il est pratiquement impossible de décrire les threads et les processus de manière non abstraite est qu'ils sont des abstractions.
Leurs mises en œuvre concrètes diffèrent énormément .
Comparez par exemple un processus Erlang et un processus Windows: un processus Erlang est très léger, souvent inférieur à 400 octets. Vous pouvez démarrer 10 millions de processus sur un ordinateur portable pas très récent sans aucun problème. Ils démarrent très rapidement, ils meurent très rapidement et vous devez pouvoir les utiliser pour des tâches très courtes. Chaque processus Erlang est associé à son propre collecteur de déchets. Les processus Erlang ne peuvent jamais partager la mémoire, jamais.
Les processus Windows sont très lourds, parfois des centaines de MiBytes. Si vous êtes chanceux, vous pouvez en démarrer quelques milliers sur un serveur costaud. Ils démarrent et meurent assez lentement. Les processus Windows sont les unités d'applications telles que les IDE, les éditeurs de texte ou les traitements de texte. Ils sont donc généralement censés vivre assez longtemps (au moins plusieurs minutes). Ils ont leur propre espace adresse, mais aucun récupérateur de déchets. Les processus Windows peuvent partager la mémoire, mais pas par défaut.
Les threads sont une affaire similaire: un thread Linux NPTL sur x86 peut être aussi petit que 4 Ko et avec quelques astuces, vous pouvez démarrer 800000+ sur une machine 32 bits x86. La machine sera certainement utilisable avec des milliers, voire des dizaines de milliers de threads. Un thread .NET CLR a une taille minimale d'environ 1 MiByte, ce qui signifie que seulement 4 000 d'entre eux occuperont l'intégralité de votre espace d'adressage sur une machine 32 bits. Par conséquent, bien que 4000 threads Linux NPTL ne pose généralement pas de problème, vous ne pouvez même pas démarrer 4000 .NET CLR Threads, car vous manquerez de mémoire auparavant.
Les processus et les threads de système d'exploitation sont également implémentés de manière très différente selon les systèmes d'exploitation. Les deux approches principales sont les suivantes: le noyau ne connaît que les processus. Les threads sont implémentés par une bibliothèque en espace utilisateur, sans aucune connaissance du noyau. Dans ce cas, il existe à nouveau deux approches: 1: 1 (chaque thread correspond à un processus noyau) ou m: n (m les threads correspondent à n processus, où généralement m> n et souvent n == #CPU). C’était la première approche adoptée sur de nombreux systèmes d’exploitation après l’invention des threads. Cependant, il est généralement jugé inefficace et a été remplacé sur presque tous les systèmes par la deuxième approche: les threads sont implémentés (au moins partiellement) dans le noyau, de sorte que le noyau connaît maintenant deux entités distinctes, Threads et Processes.
Un système d'exploitation qui passe par une troisième voie est Linux. Sous Linux, les threads ne sont implémentés ni dans l’espace utilisateur, ni dans le noyau. Au lieu de cela, le noyau fournit une abstraction de les deux un thread et un processus (et même quelques autres choses), appelée tâche. Une tâche est une entité planifiée du noyau, qui contient un ensemble d'indicateurs qui déterminent les ressources qu'elle partage avec ses frères et ses soeurs et celles qui sont privées.Selon la manière dont vous définissez ces indicateurs, vous obtenez soit un Thread (partage à peu près tout) ou un Processus (partage de toutes les ressources système telles que l'horloge système, l'espace de noms du système de fichiers, l'espace de noms réseau, l'espace de noms ID mais ne partagez pas l’espace adresse). Mais vous pouvez aussi obtenir d’autres choses très intéressantes. Vous pouvez obtenir de manière triviale des jails de style BSD (essentiellement les mêmes indicateurs qu'un processus, mais ne partagez pas le système de fichiers ou l'espace de noms réseau). Vous pouvez également obtenir ce que d'autres systèmes d'exploitation appellent un conteneur ou une zone de virtualisation (comme une prison, mais ne partagez pas les espaces de noms UID et PID et l'horloge système). Depuis quelques années, grâce à une technologie appelée KVM (machine virtuelle du noyau), vous pouvez même obtenir une machine virtuelle complète (ne rien partager, pas même les tables de pages du processeur). [La chose intéressante à propos de cela est que vous devez réutiliser le Planificateur de tâches hautement optimisé du noyau pour toutes ces choses. L'une des choses que la machine virtuelle Xen a souvent critiquées est la piètre performance de son planificateur. Les développeurs KVM ont un ordonnanceur bien supérieur à Xen, et la meilleure chose à faire est qu'ils n'ont même pas à écrire une seule ligne de code pour cela!].
Ainsi, sous Linux, les performances des threads et des processus sont beaucoup plus proches que sous Windows et de nombreux autres systèmes, car sous Linux, ils sont en réalité identiques. Ce qui signifie que les modèles d'utilisation sont très différents: sous Windows, vous décidez généralement d'utiliser un thread et un processus en fonction de leur poids: puis-je me permettre un processus ou dois-je utiliser un thread, même si je ne souhaite pas partager Etat? Sous Linux (et généralement sous Unix en général), vous décidez en fonction de leur sémantique: est-ce que je veux réellement partager un état ou pas?
Une raison pourquoi Les processus ont tendance à être plus légers sous Unix que sous Windows, mais leur utilisation est différente: sous Unix, les processus sont l’unité de base de la simultanéité et des fonctionnalités. Si vous souhaitez utiliser la concurrence, vous utilisez plusieurs processus. Si votre application peut être divisée en plusieurs parties indépendantes, vous utilisez plusieurs processus. Chaque processus fait exactement une chose et seulement cette seule chose. Même un simple script shell à une ligne implique souvent des dizaines ou des centaines de processus. Les applications consistent généralement en de nombreux processus, souvent de courte durée.
Sous Windows, les threads sont les unités de base de la simultanéité et les composants COM ou les objets .NET sont les unités de base des fonctionnalités. Les applications consistent généralement en un seul processus de longue durée.
Encore une fois, ils sont utilisés à des fins très différentes et ont des objectifs de conception très différents. Ce n'est pas que l'un ou l'autre soit meilleur ou pire, c'est juste qu'ils sont tellement / différents que les caractéristiques communes ne peuvent être décrites que de manière très abstraite.
Les seules choses que vous pouvez dire sur les threads et les processus sont les suivantes:.
Je dirais que :
Un processus a un espace mémoire, des fichiers ouverts, ..., et un ou plusieurs threads.
Un thread est un flux d'instructions pouvant être planifié par le système sur un processeur.
Jetez un coup d’œil à la réponse détaillée que j’ai donnée précédemment sur SO . Il donne un aperçu de la structure d'un noyau de jouet responsable de la maintenance des processus et des threads ...
J'espère que cela vous aidera, Cordialement, Tom.
Nous avons discuté de cette question à plusieurs reprises ici. Peut-être trouverez-vous des informations utiles ici:
Un processus est un conteneur pour un ensemble de ressources utilisées lors de l'exécution d'un programme.
Un processus comprend les éléments suivants:
Cela étant dit, un processus peut contenir plusieurs threads.
Les processus eux-mêmes peuvent être regroupés en tâches, qui sont des conteneurs pour les processus et sont exécutées en tant qu'unités.
Un thread est ce que Windows utilise pour planifier l'exécution des instructions sur la CPU. Chaque processus en a au moins un.
J'ai quelques pages sur mon wiki que vous pouvez consulter:
Physiquement:
Le processus est une structure qui conserve les informations d'identification propriétaires, la liste de threads et une liste de descripteurs ouverts.
Un thread est une structure contenant context (c'est-à-dire un ensemble de registres sauvegardé + un emplacement à exécuter), un ensemble de PTE décrivant les pages mappées dans l'espace d'adressage virtuel du processus et un propriétaire.
Ceci est bien sûr une explication extrêmement simplifiée, mais elle comprend les éléments importants. L'unité fondamentale d'exécution sous Linux et Windows est le Thread - le planificateur de noyau ne se soucie guère des processus (beaucoup). C'est pourquoi sous Linux, un thread est simplement un processus qui arrive à partager des PTE avec un autre processus.
Les threads sont des structures de mémoire dans le planificateur du système d'exploitation, comme vous le dites. Les threads pointent au début de certaines instructions en mémoire et les traitent lorsque le planificateur décide qu'elles devraient l'être. Pendant que le thread est en cours d'exécution, le minuteur matériel sera exécuté. Une fois qu'il atteint l'heure souhaitée, une interruption sera invoquée. Après cela, le matériel arrêtera alors l'exécution du programme en cours et invoquera la fonction de gestionnaire d'interruptions enregistrée, qui fera partie du planificateur, pour informer que le thread en cours est terminé.
Un processus est une zone de la mémoire gérée par le système d'exploitation pour exécuter une application. Le fil est une petite zone en mémoire au sein d'un processus permettant d'exécuter une tâche dédiée.
C'est un peu difficile de donner une réponse courte qui rend cette question justice.
Et au risque de vous tromper horriblement et de simplifier les choses, vous pouvez dire que les threads et les processus sont un concept de système d'exploitation/de plate-forme; et sous le capot, vous pouvez définir un processus mono-threadé par,
Dans les systèmes d'exploitation modernes, chaque processus a son propre espace mémoire. En plus de la mémoire partagée (seulement certains OS le supportent), le système d'exploitation interdit à un processus d'écrire dans l'espace mémoire d'un autre. Sous Windows, vous constaterez une erreur de protection générale si un processus tente de le faire.
Vous pouvez donc dire qu'un processus multithread est l'ensemble du package. Et chaque fil n'est fondamentalement rien d'autre qu'un état d'exécution.
Ainsi, lorsqu'un thread est préempté pour un autre (par exemple, sur un système mono-processeur), tout ce que le système d'exploitation doit faire est en principe de sauvegarder l'état d'exécution du thread (je ne sais pas s'il doit faire quoi que ce soit de spécial la pile) et charger dans un autre.
Préempter un processus entier, en revanche, coûte plus cher que vous pouvez l’imaginer.
Edit: Les idées s’appliquent également aux plateformes abstraites telles que Java.
Les processus et les threads sont des abstractions - il n'y a rien de physique à leur sujet, ni aucune autre partie d'un système d'exploitation D'ailleurs. C'est pourquoi nous appelons cela un logiciel.
Si vous considérez un ordinateur en termes physiques, vous vous retrouvez avec un fouillis de composants électroniques Qui émulent ce que fait une Turing Machine . Essayer de faire quelque chose d’utile avec une machine à découper crue ferait tourner votre cerveau à Jell-O en Cinq minutes à plat. Pour éviter cette expérience désagréable, les informaticiens ont développé un ensemble d’abstractions pour compartimenter divers aspects de l’informatique. Cela vous permet de vous concentrer sur le niveau d'abstraction qui vous intéresse, sans avoir à vous soucier de tout ce qui le supporte. Certaines choses ont été incorporées dans des circuits (par exemple, des additionneurs et autres), ce qui les rend physiques, mais la grande majorité de ce avec quoi nous travaillons est basée sur un ensemble d'abstractions. En règle générale, les abstractions .__ que nous utilisons ont une base mathématique sous-jacente. C'est pourquoi les piles, les files d'attente et les "états" jouent un rôle aussi important en informatique - il existe un ensemble de bases mathématiques bien fondées autour de ces abstractions qui nous permettent de construire et de raisonner leur manipulation.
La clé est de réaliser que le logiciel est toujours basé sur un composite de modèles abstraits de "choses". Ces "choses" ne se rapportent pas toujours à quelque chose de physique, mais plutôt à une autre abstraction. C'est pourquoi. Vous ne trouvez pas de base "physique" satisfaisante pour les processus et les threads Dans vos manuels.
Plusieurs autres personnes ont posté des liens et des explications sur ce que sont les threads et les processus , Aucune d’entre elles n’indique quoi que ce soit de "physique". Comme vous l'avez deviné, ils Ne sont en réalité qu'un ensemble de structures de données et de règles qui évoluent dans le contexte plus large d'un système d'exploitation (qui à son tour est constitué de davantage de structures de données et de règles ...)
Le logiciel est comme un oignon, des couches sur des couches sur des couches, une fois que vous enlevez toutes les couches (Abstractions), il ne reste plus grand chose! Mais l'oignon est toujours très réel.
J'avais vu beaucoup de réponses mais la plupart d'entre elles ne sont pas assez claires pour un débutant sous OS.
Dans n'importe quel système d'exploitation moderne, un processus possède un processeur virtuel, une mémoire virtuelle et des E/S virtuelles.
CPU virtuel: si vous avez plusieurs cœurs, le processus peut se voir affecter un ou plusieurs cœurs à traiter par le planificateur.
E/S virtuelles: les E/S peuvent être partagées entre divers processus. Comme pour un exemple de clavier pouvant être partagé par plusieurs processus. Ainsi, lorsque vous tapez dans un bloc-notes, le texte change alors qu'un enregistreur de frappe fonctionnant en tant que démon stocke toutes les frappes. Donc, le processus partage une ressource d'E/S.
Mémoire virtuelle: http://en.wikipedia.org/wiki/Virtual_memory vous pouvez passer par le lien.
Ainsi, lorsqu'un processus est retiré de l'état d'exécution par le planificateur, il contient les valeurs stockées dans les registres, sa pile et son tas, etc., sont enregistrés dans une structure de données.
Alors maintenant, lorsque nous comparons un processus à un thread, les threads démarrés par un processus partagent les entrées/sorties virtuelles et la mémoire virtuelle affectées au processus qui les a démarré, mais pas le processeur virtuel . un processus partageant tous la même mémoire virtuelle et le même bu virtuel, mais ayant différents processeurs virtuels.
Vous comprenez donc qu'il est nécessaire de verrouiller la ressource d'un processus, qu'elle soit allouée de manière statique (pile) ou allouée de manière dynamique (tas), car l'espace mémoire virtuel est partagé entre les threads d'un processus.
De plus, chaque thread ayant son propre processeur virtuel peut fonctionner en parallèle dans différents cœurs et réduire considérablement le temps d'exécution d'un processus (la réduction ne sera visible que si vous avez géré la mémoire de manière judicieuse et qu'il existe plusieurs cœurs).
Ce ne sont pas des ficelles physiques, si c'est ce que vous demandez. ;)
Si j'ai bien compris, pratiquement tout ce qui se trouve dans le système d'exploitation n'est constitué que de données. Les systèmes d'exploitation modernes dépendent de quelques exigences matérielles: traduction d'adresses de mémoire virtuelle, interruptions et protection de la mémoire (la magie matérielle/logicielle est floue au démarrage, mais je ne connais pas très bien ce processus). Une fois que ces exigences physiques sont en place, tout le reste appartient au concepteur du système d'exploitation. Ce sont juste des morceaux de données.
La raison pour laquelle elles ne sont mentionnées que de manière abstraite est qu’il s’agit de concepts; alors qu’elles seront mises en oeuvre sous forme de structures de données, il n’existe pas de règle universelle sur la manière dont elles doivent être mises en œuvre.
Ceci est au moins vrai pour les threads/processus eux-mêmes, ils ne feront pas grand chose sans un planificateur et un minuteur d'interruption.
L'ordonnanceur est l'algorithme par lequel le système d'exploitation choisit le prochain thread à exécuter pendant un temps limité et le minuteur d'interruption est un composant matériel qui interrompt périodiquement l'exécution du thread actuel et redonne le contrôle au programmateur. .
Vous avez oublié quelque chose: ce qui précède n’est pas vrai si vous n’avez que des threads coopératifs, les threads coopératifs doivent céder activement le contrôle au thread suivant, ce qui peut devenir moche avec une interrogation d’un thread pour obtenir les résultats d’un autre thread qui attend le premier.
Celles-ci sont encore plus légères que les autres threads car elles n’ont pas besoin de la prise en charge du système d’exploitation sous-jacent pour fonctionner.
Essayer de répondre à cette question relative au monde Java.
Un processus est une exécution d'un programme mais un fil est une séquence d'exécution unique dans le processus. Un processus peut contenir plusieurs threads. Un thread est parfois appelé processus poids léger.
Par exemple:
Exemple 1: Une machine virtuelle Java s'exécute dans un processus unique et les threads d'une machine virtuelle partagent le segment de mémoire appartenant à ce processus. C'est pourquoi plusieurs threads peuvent accéder au même objet. Les threads partagent le tas et ont leur propre espace de pile. C’est ainsi que l’appel d’une méthode par un thread et ses variables locales sont préservés des threads. Mais le tas n'est pas thread-safe et doit être synchronisé pour la sécurité des threads.
Exemple 2: Un programme peut ne pas être en mesure de dessiner en lisant les frappes au clavier. Le programme doit accorder toute son attention à la saisie au clavier, sans quoi il sera impossible de gérer plusieurs événements à la fois, ce qui entraînera des problèmes. La solution idéale à ce problème est l’exécution transparente de deux sections ou plus d’un programme en même temps. Les threads nous permettent de faire cela. Ici, dessiner une image est un processus et lire une frappe est un sous processus (thread).
Un thread est contrôlé par un processus, un processus est contrôlé par le système d'exploitation
Process est un conteneur de threads.
Le processus ne partage pas la mémoire entre eux - puisqu'il fonctionne dans ce qu'on appelle le "modèle plat protégé", les threads partagent la même mémoire.
Avec Windows, au moins une fois que vous avez dépassé Win 3.1, le système d'exploitation contient plusieurs processus, chacun avec son propre espace mémoire et ne peut pas interagir avec d'autres processus sans le système d'exploitation.
Chaque processus comporte un ou plusieurs threads qui partagent le même espace mémoire et n'ont pas besoin du système d'exploitation pour interagir avec d'autres threads.
Eh bien, je n'ai pas encore vu de réponse à "Qu'est-ce qu'ils sont physiquement". Alors je l'essaie.
Les processus et les threads n'ont rien de physique. Ils sont une caractéristique du système d'exploitation. En règle générale, aucun composant physique d'un ordinateur ne les connaît. La CPU ne traite qu'un flux séquentiel d'opcodes. Ces opcodes peuvent appartenir à un thread. Ensuite, le système d'exploitation utilise des interruptions et des interruptions pour reprendre le contrôle, décider du code à exécuter et passer à un autre thread.
Le processus est une entité complète, par ex. et fichier exe ou un JVM. Il peut exister un processus enfant d'un processus parent dans lequel le fichier exe est exécuté à nouveau dans un espace séparé. Le thread est un chemin d'exécution distinct dans le même processus où le processus contrôle quel thread doit être exécuté, arrêté, etc.