UN SIMPLE PROGRAMME MULTI-THREAD

SATANdemon Messages postés 44 Date d'inscription mardi 18 décembre 2001 Statut Membre Dernière intervention 30 novembre 2005 - 6 janv. 2003 à 07:54
Philippe734 Messages postés 308 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 15 juin 2015 - 25 mai 2010 à 22:39
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/5590-un-simple-programme-multi-thread

Philippe734 Messages postés 308 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 15 juin 2015 1
25 mai 2010 à 22:39
@forestlaw : oui, je crois que dans votre cas l'affaire ne sera pas réglée. Cette méthode ci-dessus est excellent juste pour soulager d'un ou deux calculs lourds. Elle n'est pas conseillée pour répartir l'ensemble des taches d'un programme dans différentes threads.
forestlaw Messages postés 1 Date d'inscription mardi 21 novembre 2000 Statut Membre Dernière intervention 25 mai 2010
25 mai 2010 à 22:32
Bonjour Philippe74,

tout d'abord merci pour votre travail à ce sujet. Il y a par contre quelques zones d'ombre que je souhaiterai éclaircir avec vous.

Je vous expose ma problématique : j'ai un base Access effectuant des traitements assez lourds. Je souhaiterai offrir à l'utilisateur la possibilité d'effectuer certains travaux en tache de fond. Par ex, je sais qu'il utilise cette base pour faire des contrôles de cohérence. Ceux-ci sont en 4 étapes. Je souhaiterai donc, pendant qu'il contrôle l'étape 1, lancer l'étape 2 en tache de fond puis l'étape 3, etc ... Le but étant qu'il ne soit quasiment jamais bloqué. Le hic est que vous dites dans votre exemple ci-dessus qu'il faut mettre les autres événements en stand by le temps que le thread finisse son travail. Je retombe donc sur le meme problème qu'avant donc non ?

Merci d'avance pour votre réponse !!!

Patrice
Philippe734 Messages postés 308 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 15 juin 2015 1
8 mai 2010 à 11:58
Afin d'illustrer mes conseils, j'ai fait une source que vous trouverez ici :
http://www.vbfrance.com/codes/DEMO-MULTITHREADING-PRISE-CHARGE-CPU-MULTI-CORE-AVEC_51734.aspx
Philippe734 Messages postés 308 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 15 juin 2015 1
1 mai 2010 à 17:51
Fonctionne aussi sous vista et seven en suivant mes conseils
Philippe734 Messages postés 308 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 15 juin 2015 1
1 mai 2010 à 16:11
Par désactiver les autres évènnemnents du programme, j'entend ce genre d'opération :
Par exemple, si dans le programme, il y a un bouton About affichant une form :
Private Sub cmdAbout_Click()
'aucune action si une thread est en cours
If ThreadEnCours = True Then Exit Sub

Load frmAbout
frmAbout.Show
End sub
Philippe734 Messages postés 308 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 15 juin 2015 1
1 mai 2010 à 16:06
Bonne source mais elle n'est pas complète. Il manque les explications permettant de réduire les risques de crash. L'usage du multithreading est certes déconseillé et souvent instable dans vb6 mais pas impossible. L'usage de cette méthode, qui repose sur l'api SHCreateThread est correcte de nos jours. En revanche, l'autre méthode reposant sur l'api CreateThread est obsolète. J'utilise cette méthode, avec l'api SHCreateThread régulièrement. Pour réduire les risques de crash, il faut ajouter des variables boolean à plusieurs endroits et désactiver les autres évènement d'un programme le temps d'exécuter la thread. C'est à dire, lors de l'exécution du thread, placer les variables avant et après afin de déterminer son statut à tout moment. Il faut également empêcher l'exécution de la thread en l'encadrant pour une condition. Avec cette méthode, il ne faut surtout pas que la sub qui lance la thread soit terminée avant la thread. Il faut attendre et mettre une boucle d'attente doevents juste après comme ci-dessous. Puis, toujours pour réduire les risques de crash, une petite boucle pour attendre quelques secondes est une bonne idée. Voici comment faire en reprenant le code de cette source :

Dans un autre module, appelons-le modGestionThreading, mettre trois property avec ses variables locales pour gérer le statut des threads

'----------------------------------------------

'dans les déclarations du module modGestionThreading :
Private m_bFinThread As Boolean
Private m_bThreadEnCours As Boolean

'dans le code du module modGestionThreading :
Public Property Get FinThread() As Boolean
FinThread = m_bFinThread
End Property

Public Property Let FinThread(ByVal bFinThread As Boolean)
m_bFinThread = bFinThread
End Property

Public Property Get ThreadEnCours() As Boolean
ThreadEnCours = m_bThreadEnCours
End Property

Public Property Let ThreadEnCours(ByVal bThreadEnCours As Boolean)
m_bThreadEnCours = bThreadEnCours
End Property

'---------------------------------------

'dans le code de l'exemple de la source :
Sub Main()

If ThreadEnCours = False Then

'on signale qu'il y a une thread en cours
ThreadEnCours = True

'initialise l'indicateur de fin de thread
FinThread = False

'crée la thread
SHCreateThread AddressOf ShowMsgBox, ByVal 0&, CTF_INSIST, ByVal 0&

'attend que la thread soit terminée
Do Until FinThread = True
DoEvents
Loop

'attend un peu que les threads soit bien terminées
Dim DebutTimer As Long
DebutTimer = Timer
Do Until (Timer - DebutTimer) >= 2 'secondes
DoEvents
Loop

'signale la fin de l'exécution des threads
ThreadEnCours = False
End If
End sub

'-----------------------------

'dans le code de la thread de la source, on ajoute la variable signalant la fin d'une thread : FinThread
Sub ShowMsgBox()
nb_t = nb_t + 1
MsgBox("Mstgbox exécuté depuis la thread n°" & nb_t, vbInformation)

FinThread = True

End Sub

Et dans le reste du programme, afin de réduire les risques de crash, il faut désactiver tout les évènements tant que la thread n'est pas terminée. Pour simplifier, le programme ne doit rien faire d'autre que la boucle Do Until FinThread = True: DoEvents: Loop
Si on veux exécuter plusieurs threads en meme temps comme dans l'exemple, alors faut modifier le test de la variable FinThread en conséquence évidemment.
En résumé, c'est contraignant, mais ca fonctionne sans crash dans vb6 sp6 et c'est reproductible. De plus, il faut compiler le programme en P-code car il réduit les risques d'instabilités. Enfin, dans la ligne "créer la thread", il faut optimiser son code afin qu'il ne s'agit que d'une sub et pas d'une function.
Reacen Messages postés 282 Date d'inscription mardi 22 août 2006 Statut Membre Dernière intervention 21 décembre 2010
21 mars 2009 à 22:21
Et mince, j'ai vraiment monter un bon Code Serveur Winsock, qui gère les clients de cette façons, mais ca marche only sur l'IDE, quand je compile mon EXE Marche jamais (-_-)... J'ai tout essayer, Natif / P-Code etc, sa donne toujours:

L'instruction à "blablabla" emploie l'adresse mémoire "blablabla". La mémoire ne peut pas être "read" Cliquez Ok pour terminer le programme...
Duke49 Messages postés 552 Date d'inscription jeudi 12 octobre 2006 Statut Non membre Dernière intervention 24 janvier 2023 4
10 mars 2009 à 01:53
J'ai fait une bourde dans l'exemple...

Dim perList() As New Collection
...
While nbThread > 0
SHCreateThread AddressOf FN_CFWT(perList), ByVal 0&, CTF_INSIST, ByVal 0&
nbThread = nbThread - 1
Wend

Je suis obligé de rendre mon perList déclaré en public ?
Duke49 Messages postés 552 Date d'inscription jeudi 12 octobre 2006 Statut Non membre Dernière intervention 24 janvier 2023 4
10 mars 2009 à 01:48
Excellent !!!

Le debug du AddressOf c'est pas facile... enfin on y peut rien.
J'ai une question plus importante.
Si je souhaite faire transiter une collection, comment je fait ???

exemple qui passe pas ^^:

Dim FN_CFWT() as New Collection
...
While nbThread > 0
SHCreateThread AddressOf FN_CFWT(nbThread), ByVal 0&, CTF_INSIST, ByVal 0&
nbThread = nbThread - 1
Wend
hkari Messages postés 2 Date d'inscription dimanche 24 décembre 2000 Statut Membre Dernière intervention 12 novembre 2008
9 nov. 2008 à 11:27
je suis débutante dans la programmation des threads en C++builder6.
je cherche la fonction qui me permet de mettre en attente des threads (la fonction wait en java). je cherche sa correspondance en C++builder6.

merci de votre aide
cs_jipef Messages postés 55 Date d'inscription lundi 23 août 2004 Statut Membre Dernière intervention 1 août 2008
23 août 2008 à 15:24
sous vista ça merde completement
Reacen Messages postés 282 Date d'inscription mardi 22 août 2006 Statut Membre Dernière intervention 21 décembre 2010
9 août 2008 à 09:09
Et On quoi cette source t'a sauver la vie ? x')

Sinon simple source et parfaite ! 10/10!!

Tien, je peu aller juska combien de fois avec ca :

For i = 1 To 50
SHCreateThread AddressOf ShowMsgBox, ByVal 0&, CTF_INSIST, ByVal 0&
next i

C'est fesable x') ?
bastoche34 Messages postés 1 Date d'inscription lundi 12 mars 2007 Statut Membre Dernière intervention 31 août 2007
31 août 2007 à 11:01
Merci tu me sauve la vie!!!!!
j'était persuader qu'on ne pouvez pas faire de thread en VB6
ZedMaTrix Messages postés 178 Date d'inscription vendredi 25 octobre 2002 Statut Membre Dernière intervention 14 août 2008
27 août 2005 à 02:03
C'est super ce code !!

Mais plus d'explications sur la création de thread please !
cs_Fedaykin Messages postés 12 Date d'inscription mardi 23 avril 2002 Statut Membre Dernière intervention 3 septembre 2004
26 mars 2004 à 17:02
merci,

code rapide, relativement simple,
et qui fonctionne très bien

10/10

:)
lumesh Messages postés 564 Date d'inscription jeudi 21 février 2002 Statut Membre Dernière intervention 7 novembre 2008
7 juil. 2003 à 17:04
Salut,

voila je suis en train de faire une appli de client FTP
et dedans g un systeme de recherche recursif. qui est assez lourd
donc je voulais le mettre ds un thread mais je c pas men servir donc g pris ta src mais
le truc c ke je dois passer un param a la fonction a mettre en thread, donc saurait comment je px faire STP ?

MErci par avance pour ta réponse :)
oliv211 Messages postés 25 Date d'inscription mercredi 11 septembre 2002 Statut Membre Dernière intervention 2 septembre 2004
6 janv. 2003 à 09:03
>SATANdemon
un thread c un "processus leger" (c comme ca qu'on traduit).. en fait t'as la notion d'appartement qui vient en plus, c assez compliqué pour ne pas être expliqué en 2lignes, juste à retenir que VB est nul ds la gestion des threads, et que C++ y excelle... sinon ca sert surtout quand un composant est appelé simultanément par plusieurs "clients" .... c du gros resumé car c compliqué ;)
SATANdemon Messages postés 44 Date d'inscription mardi 18 décembre 2001 Statut Membre Dernière intervention 30 novembre 2005
6 janv. 2003 à 07:54
Pouurait tu m'expliquer ce qu'est un thread ??
moi et l'anglais on fait 5 si tu voit ce que je veut dire ;)

mais sinon je pense que ca pourra me servir un de ces jour :)