Hello les gens,
Qqn peut-il me dire ce qu'est un 'threads', et comment ça marche ?
Merci les pitchounettes ...
Version imprimable
Hello les gens,
Qqn peut-il me dire ce qu'est un 'threads', et comment ça marche ?
Merci les pitchounettes ...
Un « thread », littéralement, ça veut dire « fil ». Dans le principe, ça veut dire qu'il va y avoir deux instances en train d'interpréter le même programme au sein du même processus.
Imagine par exemple que tu fasses un programme qui gère une interface graphique et qui déclenche une action quand on clique sur un bouton. Fort bien, mais l'interface reste alors indisponible pendant toute la durée de l'action, jusqu'à ce que le processus finisse ce qu'il est en train de faire et puisse retourner à sa tâche de surveillance de l'interface.
S'il y a deux fils d'exécution en parallèle au sein du même environnement, il y en a un qui peut rester au guichet pendant que l'autre, en coulisse, fabrique les petits pains :-)
Un thread est une fonction qui s'éxecute en parallèle à ton programme.
Un thread c'est quoi?
c'est juste une fonction au sein de ton programme ( le processus qui s'affiche dans ton gestionnaire des taches win )
contrairement aux fonctions d'un programme dit je cite a processus unique
qui s'execute en sequence, la fonction d'un thread s'execute en parrellel avec d'autre threads ( en faite c'est plutot du pseudoparallelisme puisque le processeur bascule plus rapidement d'un thread vers un autre que d'un processus vers un autre ).
C'est tu veux voir les threads en execution ( si tu le sais pas encore )
il suffit d'aller vers le gestionnaire des taches dans le sous menu affichage, tu selectionne l'option poour afficher les colonnes, dans la fenetre modale tu choisi d'afficher les threads
Bonjour;
Meme sur linux il y'a des threads si on utilise unistd.h
puis on utilise fork(),join()...
Mais c'est mieux sur windows ;-)
fork, join ou thread meme combat, ça part du meme principe, le parallelisme.
en plus j'ai rien contre linux, je suis entrain de quitter windows ;-)
il y'a une instruction qui s'appele clone(); ça se trouve ou ça, je suis curieux !
Le principe est peut-être le même, mais fork != thread. Un fork, c'est un new process qui hérite de son père tout le bazzare. Un thread, c'est le même process qui fait un "schisme". Quand tu fais un fork(), tu dupliques tous les threads du process.
Les threads sous windows ne sont pas POSIX (I believe...), mais contrôle avant de prendre au mot ce que je dis.
Un petit lien:
Code:http://gauss.ececs.uc.edu/Users/Franco/ForksThreads/forks.html
Pas le même combat du tout ! fork(), join() et autres, ça crée des nouvelles instances du programme, des nouveaux processus (qui apparaissent donc dans le gestionnaire des taches). Ces instances ne partagent pas de variables, pas de mémoire.
Deux threads au sein d'un même processus partagent leur mémoire, les variables, ...
Bonjour,
il y a bequcoup d'erreurs dans les réponses qui ont été données ici. Pour continuer sur la lancée de Matthieu, je vais essayer de remettre les choses au clair.
Faux. Il ne faut pas confondre thread (que l'on peut trouver dans la littérature sous le nom de processus léger) et processus. Dans le gestionnaire des tâches Windows, ce ne sont pas les threads qui apparaissent, ce sont les processus.
C'est vrai dans le cas d'une machine qui n'a qu'un processeur et un seul noyau. Dans le cas où l'on plusieurs processeurs (ou plusieurs noyaux) et que nos threads sont "bien programmés", les threads s'exécutent réellement en même temps, sur des processeurs (ou noyaux) différents.
Non, un thread s'exectue à l'intérieur du programme. Deux threads s'exécutent en parrallèle.
Comme il a été dit, rien à voir.
Affirmation péremptoire s'il en est. Je ne vois pas en quoi c'est mieux sous windows, j'aurais même tendance à dire l'inverse. Cela dit, je suis disposé à réviser mon jugement si de bons arguments sont avancés.
En fait, pour résumer:
* Au début, tu as le programme P, ou processus. Quand le programme se lance, il s'accapare un morceau de mémoire.
* Ce programme P va faire des actions (lire des fichiers, faire des calculs, afficher des trucs à l'écran, etc...). Pour chacune de ces actions (pour simplifier) il va faire appel au processeur.
* Si dans ce programme P tu veux faire 2 choses en même temps, tu vas avoir besoin de créer un ou plusieurs threads. L'exemple classique c'est une application avec une interface graphique. Tu va lancer un thread T1 qui gère l'interface graphique, ainsi ton programme (ou processus) qui gère les données ne sera pas emmerdé s'il y a des soucis avec ton interface graphique, et vice-versa. Dans cet exemple, nous avons un seul thread T1, qui gère l'interface graphique, et un programme (ou processus) qui gère les données. T1 utilise la mémoire de P (alors que si on a un autre programme P2, ce dernier ne partagera pas la mémoire de P). Dans P, si tu crée un autre thread T2, (exemple typique, effectuer une lecture continue sur une ressource (port serie, usb, ethernet, bdd, lecteur CD, etc.) ) il partagera la mémoire de P et de T1.
Voilà, j'espère que ça éclaire un peu :)
clone() est un appel spécifique à Linux. Il te permet de faire en quelque sorte un fork() paramétré, en précisant ce qui doit être partagé entre le processus père et son fils, et ce qui doit rester commun. À l'extrême, tout est dupliqué et cela réalise un fork() normal, à l'autre extrême, tout est partagé et la seule chose qui change est le PID.
Ça a effectivement l'air « bidouille » vu de l'extérieur parce que l'on voit les threads traîner dans le ps, alors qu'en fait, c'est un moyen très pratique de ne pas réinventer la roue, et de pouvoir continuer à utiliser les mêmes outils. Tu peux tuer un thread, le débugger à la volée avec gdb comme tu le ferais avec un processus ordinaire, etc.
De toutes façons, les threads sous UNIX sont généralement exploités au travers de bibliothèques comme pthreads ou linuxthreads.
https://computing.llnl.gov/tutorials/pthreads/
http://pauillac.inria.fr/~xleroy/linuxthreads/
http://pwet.fr/man/linux/appels_systemes/clone
bah maintenant avec boost::thread, moi c'est vite vu: comme de toutes façon j'utilise tout le temps boost, que les threads de boost sont très bien, que c'est du c++ (alors que la plupart des libs de threading c'est du C) et qu'ils sont multi-plateforme. Que demander de plus?
C'est vrai pour l'histoire du fork et du join, je me trompe, c'est lamentable
Concernant la confusion entre thread et processus, je voulait afficher les threads d'un processus avec le gestionnaire des taches :
ctrl+alt+del
selectionner onglet Processus
menu->affichage->selectionner les colonnes
Dans la boite de dialogue on coche la case Nombre de threads.
C'est ça que je voulait dire mais le message n'est pas passé
Concernant les autre système d'exploitations style linux, il faut avoir une tres tres bonne machine, je m'explique :
j'ai une machine avec 512 MO de ram un processeur AMD 1.7 G
Je compile qt4 sur windows, ça prend 2 heures
je compile qt4 sur mandriva 2007, ça dure 5 heures !!!!!
Ben le constat est simple linux à des probleme avec ses processus et ses threads
Je les ai installé sur la meme machine windows et linux ?
Au temps pour moi, c'est bien que tu disais dans ton post, j'avais mal compris.
Un peu de rigueur, que diantre. La seule conclusion que l'on peut tirer de ce test c'est: "dans les conditions dans lesquelles tu as effectué l'opération, qt4 compile plus vite sous windows que sous linux". Mais:
-> nous ne connaissons pas les conditions de ton test. La commande de compilation sous chacun des os par exemple, utilisation ou non de l'os pendant la compil, processus qui tournent, compilo utilisé, etc, etc...
-> une mauvaise gestion des thread peut être la raison effectivement, mais ça peut également en être des milliers d'autres. Pourquoi choisir celle-là? Si effectivement, qt4 compile plus vite sous windows que sous linux - ce qui reste à prouver, mais il faudrait faire de vrais tests - il y a de fortes chances pour que l'explication n'ait à peu près rien à voir avec la gestion des threads.
-> vu le nombre d'erreurs, d'approximations et de phrases péremptoires dans tes précédents posts, j'ai du mal à prendre réellement au sérieux tes récentes affirmations.
Et, quand tu compiles, tu utilises forcément des threads ? Je suis sûr que l'une de tes deux compils n'était pas parallélisée !
Non, franchement, sans méchanceté, ce n'est même pas de la guerre de clochers, ici. Tu as fait l'effort de lancer des compilations sur plusieurs systèmes et malgré ça, tu vas passer pour un âne devant n'importe quel employeur, si tu tires ce genre de conclusions.
C'est vrai que c'est vraiment approximatif, désolé pour ça !
Bon la première fois que j'ai utilisé un ordinateur remonte à il ya 3 ans ce qui est relativement cours:oops:
Concérnant le compilation de Qt sous linux, ben j'ai attendu 5 heures pour que Qt me gènère les fichiers "executables". je suis resté 5 heurs à regarder les instructions défiler.
Concérnant les conditions de compilation :
Sur windows:
Le compilateur est MinGW:( c'est du GNU )
sur cmd je tappe configure, pui make
Sur linux , je rentre dans le dossier comportant les sources de qt
je déclache l'execution de fichier sh "configure"
ensuite je tappe;
gmake
puis j'attend 5 heures 8O
C'est pas du tout le même compilateur que tu utilises, pas forcément les mêmes options de compilation (peut-être plus de bibliothèques additionnelles sous Linux), mais surtout gcc.
GCC 4.x est assez lent, mais ça vaut la peine par la suite (cf mon message précédent).
Il est fort probable que tu n'aies pas tout compilé (ni d'un côté, ni de l'autre, d'ailleurs). ./configure sert notamment à cela : sélectionner les composants qui doivent être construits ou non. Et ceux-ci sont choisis en fonction de ton environnement. Avec MinGW sous Windows, celui-ci devait être minimum, et la compilation t'a construit un truc en rapport.
Ensuite, as-tu vérifié pendant la compilation que le compilateur sous Windows lançait bien des threads ou n'est-ce qu'une supposition ?
Enfin, comme dit plus haut, il faut passer l'option -j à make pour lui demander de lancer plusieurs jobs à la fois (ce ne sont pas à proprement parler des threads, toutefois).
Suis le lien http://www.developpez.net/forums/d57...e/#post3428127
On va pas en faire toute un plat :D
De toute maniere, tous les OS marchent pareil, et je n'ai jamais vu de différence entre Linux et Windows de ce coté... A part, peut-être un accès plus facile sous Windows SDK à certaines fonctions (comme la sélection du CPU préféré pour le thread, la priorité d'execution, ...), mais je ne suis pas un fin connaisseur de tous les noyaux unix (et tous les unix ne sont pas égaux devant les threads).
Quand on "lance" un programme, l'OS crée un "processus" (allocation mémoire, mapping mémoire virtuelle, chargement du code, handles d'entrée/sortie, ...), puis alloue un thread à ce processus (parfois appelé thread principal) pour executer le point d'entrée du processus ("main") qui dépend de l'OS.
Ensuite, rien n'empêche ce thread principal de créer d'autres threads additionels au sein du même processus.
Un thread regroupe un "état de fonctionnement CPU" (code actuel, pile, registres), le passage d'un thread à un autre "coute" cher (mais largement moins que sa création), mais permet entre autre, de continuer à faire des choses pendant qu'on attend autre chose (en général de l'I/O comme la lecture de fichier, le réseau, la carte graphique ou la carte son, ou bien attendre un évenement précis comme une heure donnée, une exception, etc...).
Un thread n'est pas un vrai processus, même sous Linux. On l'appelle processus léger, mais ce n'est pas un processus en tant que tel.
Côté compréhension, nombre de difficultés proviennent du fait qu'un "thread" est (ou pas) une entité gérée par l'ordonnanceur de "processus".
Si les threads crées par/dans un processus sont gérées par l'ordonnanceur on parlera de correspondance 1x1 entre l'ensemble des objets gérés par l'ordonnanceur et l'ensemble des threads crées par les processus "actifs".
Il existe un modèle de threading (plus léger) qui fait une correspondance MxN. Dans ce modèle, un process multi-threads dispose d'un ordonnanceur de premier niveau qui les multiplexe sur des threads de 2nd niveau (qui sont elles gérées par l'ordonnanceur de processus).
A ma connaissance, Linux implémente, par défaut, un modèle 1x1.
- W
To the Linux Kernel, there is no concept of a thread. Linux implements all threads as standart processes. ... Instead, a thread is merely a process which shares certain resources. Each thread has a unique task_struct and appear to the kernel as a normal process (which shares resources, such more as an address space, with other processes)
Linux Kernel Development Robert Love
Il faut donc bien distinguer programme, processus et thread. ;)
Où M et N sont ?
Je suppose que M=threads et N=processus.
Ok, mais cet ordonnanceur de premier niveau, lui, fonctionne comment ? Sans être un expert, je me dis qu'il doit être soit coopératif, et dans ce cas, ça implique beaucoup de prérequis, soit préemptif comme les autres et dans ce cas, il fait double emploi avec l'ordonnanceur de processus normal (avec possibilité de concurrence).Citation:
Dans ce modèle, un process multi-threads dispose d'un ordonnanceur de premier niveau qui les multiplexe sur des threads de 2nd niveau (qui sont elles gérées par l'ordonnanceur de processus).
Si on affine l'ordonnanceur pour définir ce qui est partagé ou pas, et que l'on groupe les processus en session (comme ça se fait déjà sur Unix), il n'y plus rien qui distingue un processus d'un thread. Et il me semble que c'est bien ce que fait clone().
Plus précisément M threads de premier niveau qui peuvent être exécutée par N threads de second niveau (inutile d'avoir N grand devant le nombre de CPU par exemple).Citation:
Par définition, la préemption sert à suspendre un thread actif suffisament longtemps alors que d'autres threads n'attendent que la libération d'unCitation:
Ok, mais cet ordonnanceur de premier niveau, lui, fonctionne comment ? Sans être un expert, je me dis qu'il doit être soit coopératif, et dans ce cas, ça implique beaucoup de prérequis, soit préemptif comme les autres et dans ce cas, il fait double emploi avec l'ordonnanceur de processus normal (avec possibilité de concurrence).
processeur pour s'exécuter.
On peut donc laisser faire la préemption par l'ordonnanceur de second niveau.
Quelque soit le modèle de threading, un processus est définit par un espace d'adressage virtuel et l'ensemble des threads qui le partagent.Citation:
Si on affine l'ordonnanceur pour définir ce qui est partagé ou pas, et que l'on groupe les processus en session (comme ça se fait déjà sur Unix), il n'y plus rien qui distingue un processus d'un thread. Et il me semble que c'est bien ce que fait clone().
Il y a quelques subtiles différences entre:
- la création de la première thread impliquant celle au préalable de l'espace virtuel
- l'ajout de thread à l'objet précédemment crée.
Et le mélange systématique entre le "quoi" et les implémentations réalisées n'aide pas à faire la différence entre l'essentiel et le spécifique.
- W
Il me semble que sous Linux, l'implémentation du multithreading a changé:
- Avant l'invention de la NPTL, les différents threads d'un processus étaient gérés par le processus lui-même, mais pour le Kernel il n'y avait toujours qu'un et un seul processus.
- Depuis la NPTL, les threads sont des processus qui partagent une grosse part de ressources.
Sous Windows NT, le kernel a toujours fait la différence entre processus et threads. Par contre, j'ignore ce qu'il en est pour les fibres.
Si on garde la définition du multithreading comme étant "plusieurs fils ordonnançables indépendament" qui partagent le même espace d'adressage (virtuel), certaines libraries proposent un mécanisme parfois appelé "user level threads" dans lequel le noyau n'a aucune connaissance des "threads" crées dans/par le processus.
=> Plusieurs threads sont "multiplexées" dans un même processus.
Cette approche à l'inconvénient de ne pouvoir profiter du nombre de processeurs dont pourrait disposer le système, ce qui limite les capacités de traitement à un seul CPU. Pour ce faire, il faut des entités ordonnançables par le noyau (des kernel threads).
D'ou l'intérêt de différencier:
- "users threads" : threads dont le noyau n'a pas connaissance et qui ne sont ordonnançables que par/depuis le process (ou plus précisément la librarie qui les gère).
- "kernel threads" : threads ordonnançées par le noyau comme le sont des process mais qui partageant nombre de ressources (espace virtuel, mémoire résidente,...) sont un peu différent du processus classique.
Sous Solaris, les "users threads" s'appellent simplement "threads" alors qu'elles sont nommées "fibers" sous Windows. De même les "kernel threads" sont désignées par LWP sous Solaris (LWP = Light Weight Process) et simplement threads sous Solaris.
Windows semble ne proposer que des objets élémentaires fibers et threads, charge au développeur de créer l'ordonnanceur via "switchtofiber" - ce n'est pas des plus simple - alors que Solaris propose un ordonnanceur.
- W
Ce qu'il faut distinguer, c'est les threads noyau, aussi appelés LWP (lightweight processes) et les threads utilisateur.
Les threads noyau sont plus coûteux, passent moins bien à l'échelle, mais ils sont capable d'être placés sur différents cœurs hyperthreadés, cœurs, processeurs, etc.
Les threads utilisateur souffrent du fait que tout appel bloquant bloque tous les threads, ce qui peut se résoudre en remplaçant ces appels par l'équivalent non bloquant et en laissant l'ordonnanceur de threads utilisateur gérer le reste pour donner un comportement bloquant. Une alternative est aussi de déclencher un thread noyau pour ces cas-là.
Linux ne fournit que des threads noyau.
Libre à toi de faire au sein de ces threads noyau d'autres threads utilisateur, ce qu'on appelle du N:M.
C'est un sujet super interressant, je squatte :mrgreen: !
Quelles sont les (autres) différences notoires entre ce que permettent Windows, Linux et solaris?
Par exemple les fibres (que vous m'avez fait découvrir - merci) sont elles disponibles sur ces trois plateformes? Les bacs à threads (traduction perso de thread pool), les conditions et tout ça ?...
euuuhhh merci à tous ...