Tutorial sur le multi-threading en Visual C++

Tutorial sur le multi-threading en Visual C++ - Programmation

Marsh Posté le 16-05-2001 à 13:26:40    

Bonjour,
 
Je cherche un tutorial ou quelqu'un qui pourratit m'aider à comprendre et utiliser le multi-threading en Visual C++.
J'ai développé un client FTP, mais lorsque je lance un téléchargement, le programme se freeze tant que le transfert du fichier n'est pas terminé !
Pour remédier à cela, on m'a dit de faire du multi-tâches (ce qui me semble logique), mais je ne sais pas comment l'utiliser, et je ne trouve pas de tutoriaux sur ce sujet...
Si quelqu'un peut m'aider, ou me faire comprendre comment ça marche, quelles fonctions utiliser, dans quelles bibliothèques ?
Merci d'avance,

Reply

Marsh Posté le 16-05-2001 à 13:26:40   

Reply

Marsh Posté le 16-05-2001 à 14:02:36    

regardes la fonction beginthread ou beginthreadex (pour NT) dans le MSDN. C'est une des fonctions qui permet de lancer un thread sous windows.
 
Désolé, pas le temps d'en dire bien plus.
Mais regardes un peu l'historique du forum. Ya eu plein de topics sur ce sujet. Les réponse à ta questions y sont déjà.
 
a+

Reply

Marsh Posté le 16-05-2001 à 17:11:08    

beginthread  et endthread sont a éviter. utilise plutôt beginthreadex et endthreadex.
 
il y aussi CreateThread.

Reply

Marsh Posté le 16-05-2001 à 19:58:26    

Ok ! Merci pour les conseils ;)

Reply

Marsh Posté le 16-05-2001 à 20:52:38    

tu utilise les MFC? Parce que si c'est le cas, faut utiliser
AfxBeginThread
 
par contre, si tu veux que ta fonction thread soit une methode d'un objet (propre comme en java par exemple) c'est pas evident et faut ruser...

Reply

Marsh Posté le 17-05-2001 à 09:47:51    

J'utilise bien les MFC, mais en fait ce que je recherche le + c'est pas le code, ce sont surtout les modes de fonctioonement du multi-thread ?
En fait j'ai créé un client FTP, et j'aimerai qu'une simple procédure soit appelée en parallèle avec une autre : par exemple j'aimerai que la procédure de téléchargement soit appelée en même temps que celle affichant la barre de progression et qu'en + de cela permette à l'utilisateur de se ballader dans l'application sans avoir besoin d'attendre la fin du téléchargement ?

Reply

Marsh Posté le 17-05-2001 à 09:56:45    

ben c'est simple, tu mets tes 2 procedures dans 2 threads differents en appelant 2 fois AfxBeginThread avec en param un pointeur vers ta procedure. Si t'as pas envie de modifier l'interface de ton appli (interface logicielle = prototype de tes fonctions), tu cree 2 petites fonctions qui ont le bon proto
UINT blablabla(LPVOID param) qui vont a leur tour appeler tes 2 autres procedures.
Fais ensuite gaffe a la synchro, c'est le point le plus delicat avec le multi-threading.

Reply

Marsh Posté le 17-05-2001 à 10:23:18    

Bon, je vais essayer de me débrouiller pour l'instant !
 
Merci pour l'aide, même si je ne suis pas sur d'avoir tout compris ;-) Je ne fais du Visual C++ que depuis 1 mois :)

Reply

Marsh Posté le 17-05-2001 à 10:27:55    

En fait j'aurais une dernière petite question :
La fonction AfxBeginThread me renvoie un CWinThread*, donc il faut que je crée autre chose avant ?
 
Deuxième petite question, je ne vois pas trop à quoi correspondent les types utilisés pour la déclaration de ma fonction appelée dans mon thread ? En effet on me demande de déclarer une fonction de type
             UINT MaFonction (LPVOID pParam);
les UINT et le LPVOID correspondent à quoi exactement ?
 
Merci d'avance ;)

Reply

Marsh Posté le 17-05-2001 à 10:32:31    

guillot a écrit a écrit :

En fait j'aurais une dernière petite question :
La fonction AfxBeginThread me renvoie un CWinThread*, donc il faut que je crée autre chose avant ?
 
Deuxième petite question, je ne vois pas trop à quoi correspondent les types utilisés pour la déclaration de ma fonction appelée dans mon thread ? En effet on me demande de déclarer une fonction de type
             UINT MaFonction (LPVOID pParam);
les UINT et le LPVOID correspondent à quoi exactement ?
 
Merci d'avance ;)




UINT ce doit etre un unsigned int
LPVOID un void *.

Reply

Marsh Posté le 17-05-2001 à 10:32:31   

Reply

Marsh Posté le 17-05-2001 à 10:36:17    

arf =)
Ok merci !

Reply

Marsh Posté le 17-05-2001 à 11:04:51    

Rhaaaaaa ! En fait j'y pane rien du tout :)
je ne vois toujours pas comment ça marche...
 
En fait en reprennant depuis le début, voilà ce que j'en ai compris :
 
- Il faut que je déclare un objet de type CWinThread servant à recevoir le thread commencé par AfxBeginThread + loin
 
- Il faut appeler la méthode AfxBeginThread, lui passer des paramètres. Le 1er est un pointeur vers une fonction de type UINT MaFonction(LPVOID param). Certes, mais cette fonction elle sert à quoi ? Je met quoi dedans ? Je lui passe quoi en paramètre ?
 
Après ça, je devrais avoir mon thread créé pis là j'aurais d'autres soucis :)
 
 
C'est pour ça qu'un tutorial m'aurait bien servi... :(

Reply

Marsh Posté le 17-05-2001 à 11:25:25    

Je ne connais pas le MultiThreading de Windows, mais celui de POSIX, toutefois voici des principes de base :
Une (un) Thread est un nouveau chemin d'execution dans ton programme.
Lorsque tu crees des Threads tu doit leur donner une fonction a executer, c'est en quelque sorte leur "main". Ces Threads une fois crees executent cette fonction puis meurent.
Les variables allouees sur le tas et globales sont communes a tous les threads, par contre les locales ne sont definies que dans un thread, donc pour faiure communiquer deux threads sans globales tu utilise le pointeur que recoit ta fonction sachant que sa valeur est celle que tu passe a la fonction qui cree la thread...
Par contre il ne faut pas que deux threads ecrivent en meme temps dans une variable (ou qu'un ecrive pendant qu'un autre lise) donc il faut des synchronisations. Elles sont de differents types : les mutex sont des elements qui verouillent une section de code, seule une thread peut executer cette section, si une autre thread doit executer le meme code elle attends (au lock du mutex) que la precedente sorte (unlock du mutex). les synchro permettent de bloquer une thread (wait, join) jusqu'a ce qu'une autre la debloque...
 
Pour revenir a quelque chose de plus concret je pense que CWinThread est un objet qui permet de materialiser la thread tu doit donc juste declarer un pointeur pour recevoir cet objet (je ne pense pas que ce soit necessaire, mais il n'y a pas d'equivalent en POSIX, peut etre doit il etre detruit a la fin de la thread.
Il existe des methodes qui permettent de detruire une thread depuis une autre... leur usage est tres fortement deconseille, pour ma part je le prohibe... car souvent il equivaut a une auto-destruction du programme.
 
Enfin il existe un biblio libre (LGPL plutot) wxWindows (www.wxwindows.org) qui propose une alternative aux MFCs qui est multi plateforme et propose des objets pour utiliser les Threads qui ne dependent donc plus de l'implementation (Windows, SUN, HP, etc) tu peux aller regarder l'objet wxThread.

Reply

Marsh Posté le 17-05-2001 à 11:25:47    

Donc:
 
1. Le CWinThread, tu peux le laisser tomber pour le moment.
2. Les threads ont tous un "fil d'execution" c'est la procedure qui va etre execute. La fonction AfxBeginThread renseigne le scheduler du systeme et ensuite l'execute. En gros, le 1er param de AfxBeginThread, c'est la fonction qui va etre execute en "parallele" de ton prog principal.  
Pour que le systeme puisse appeler la fonction que tu passe en param a Afx..., tu dois respecter un certain canevas fixe par MS
UINT thread (LPVOID param)
 
UINT : la valeur de retour c'est pour eventuellement montrer qu'il y a eu une erreur
LPVOID c'est un void *, tu peux mettre la dedans ce que tu veux comme donne, typiquement, tu y mets un pointeur vers un objet qui aggrege les params des fonctions deja ecrites.
Supposons que t'as une fonction  
void download(char* arg1, int arg2, CString arg3)
et que c'est cette fonction que tu veux executer ds un thread.
Et bien au lieu de modifier son interface,
tu cree une 2eme fonction
UINT thread1(LPVOID ptr)
{
  CObjArgs *oa=(CObjArgs *)ptr;  
/*CObjArgs contient le arg1, arg2, arg3 (tu peux mettre une struct si ca te plait mieux*/
 
 return download(oa->getArg1(),oa->getArg2(),oa->getArg3());
}

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed