begin process at 2012 02 13 07:22:40
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

API

 > UN SIMPLE PROGRAMME MULTI-THREAD

UN SIMPLE PROGRAMME MULTI-THREAD


 Information sur la source

Note :
9,43 / 10 - par 7 personnes
9,43 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :API Niveau :Initié Date de création :05/01/2003 Date de mise à jour :05/01/2003 21:40:01 Vu :7 910

Auteur : vbmore

Ecrire un message privé
Site perso
Commentaire sur cette source (18)
Ajouter un commentaire et/ou une note

 Description

On peut facilement créer une app. mutli-thread avec VB grace au VB !
Mais attention, c'est risqué ! (ça plante pour un rien)

A mettre dans un module et sub main en démarrage

Source

  • Public Const CTF_COINIT = &H8
  • Public Const CTF_INSIST = &H1
  • Public Const CTF_PROCESS_REF = &H4
  • Public Const CTF_THREAD_REF = &H2
  • Public Declare Function SHCreateThread Lib "shlwapi.dll" (ByVal pfnThreadProc As Long, pData As Any, ByVal dwFlags As Long, ByVal pfnCallback As Long) As Long
  • Private Declare Function GetCurrentThread Lib "kernel32" () As Long
  • Dim nb_t& ' Nombre de thread
  • Sub main()
  • ' On crée les thread
  • SHCreateThread AddressOf ShowMsgBox, ByVal 0&, CTF_INSIST, ByVal 0&
  • SHCreateThread AddressOf ShowMsgBox, ByVal 0&, CTF_INSIST, ByVal 0&
  • SHCreateThread AddressOf ShowMsgBox, ByVal 0&, CTF_INSIST, ByVal 0&
  • MsgBox "Vous devez fermer les autres boites de dialogue avant de fermer celle-la", vbCritical, "Attention"
  • End Sub
  • Sub ShowMsgBox()
  • nb_t = nb_t + 1
  • Call MsgBox("Mstgbox executé depuis la thread n°" & nb_t, vbInformation, "Multi-Thread")
  • End Sub
Public Const CTF_COINIT = &H8
Public Const CTF_INSIST = &H1
Public Const CTF_PROCESS_REF = &H4
Public Const CTF_THREAD_REF = &H2

Public Declare Function SHCreateThread Lib "shlwapi.dll" (ByVal pfnThreadProc As Long, pData As Any, ByVal dwFlags As Long, ByVal pfnCallback As Long) As Long
Private Declare Function GetCurrentThread Lib "kernel32" () As Long

Dim nb_t& ' Nombre de thread

Sub main()
    ' On crée les thread
    SHCreateThread AddressOf ShowMsgBox, ByVal 0&, CTF_INSIST, ByVal 0&
    SHCreateThread AddressOf ShowMsgBox, ByVal 0&, CTF_INSIST, ByVal 0&
    SHCreateThread AddressOf ShowMsgBox, ByVal 0&, CTF_INSIST, ByVal 0&
    
    MsgBox "Vous devez fermer les autres boites de dialogue avant de fermer celle-la", vbCritical, "Attention"
End Sub

Sub ShowMsgBox()
    nb_t = nb_t + 1
    Call MsgBox("Mstgbox executé depuis la thread n°" & nb_t, vbInformation, "Multi-Thread")
End Sub



 Sources du même auteur

OBTENIR À L'AVANCE LA TAILLE D'UN TEXTE DESSINÉ SUR UNE FORM...
COPIER UNE STRUCTURE "TYPE" DANS UNE AUTRES
IMPRIMER N'IMPORTE QUEL FICHIER
Source avec Zip EVENT QUAND LA FORM BOUGE (SUBSCLASSING)
Source avec Zip ENUMÈRER LES SECTIONS D'UN FICHIER .INI

 Sources de la même categorie

Source avec Zip Source .NET (Dotnet) .NET DEPENDENCY VIEWER : ARBRE DES DÉPENDANCES D'UN ASSEMBLY... par ShareVB
Source avec Zip Source .NET (Dotnet) UTILITAIRE SKYDRIVE par MasterShadows
Source avec Zip ROTATION RAPIDE D'IMAGE par trex70
Source avec Zip Source avec une capture ENUMERATION DES PORTS TCP ET IDENTIFCATION DU PROCESS (PID) ... par Renfield
Source avec Zip Source avec une capture MOUSE SPEED AND WEIGHT : RETOUR DE FORCE VIRTUEL ! par ScSami

Commentaires et avis

Commentaire de SATANdemon le 06/01/2003 07:54:40

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 :)

Commentaire de oliv211 le 06/01/2003 09:03:31

>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é ;)

Commentaire de lumesh le 07/07/2003 17:04:25

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 :)

Commentaire de Fedaykin le 26/03/2004 17:02:25

merci,

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

10/10

:)

Commentaire de ZedMaTrix le 27/08/2005 02:03:46

C'est super ce code !!

Mais plus d'explications sur la création de thread please !

Commentaire de bastoche34 le 31/08/2007 11:01:14

Merci tu me sauve la vie!!!!!
j'était persuader qu'on ne pouvez pas faire de thread en VB6

Commentaire de reacen le 09/08/2008 09:09:28 10/10

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') ?

Commentaire de jipef le 23/08/2008 15:24:52

sous vista ça merde completement

Commentaire de hkari le 09/11/2008 11:27:16

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

Commentaire de Duke49 le 10/03/2009 01:48:08

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

Commentaire de Duke49 le 10/03/2009 01:53:58 10/10

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 ?

Commentaire de reacen le 21/03/2009 22:21: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...

Commentaire de Philippe734 le 01/05/2010 16:06:39 8/10

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.

Commentaire de Philippe734 le 01/05/2010 16:11:15

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

Commentaire de Philippe734 le 01/05/2010 17:51:41

Fonctionne aussi sous vista et seven en suivant mes conseils

Commentaire de Philippe734 le 08/05/2010 11:58:34

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

Commentaire de forestlaw le 25/05/2010 22:32:09

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

Commentaire de Philippe734 le 25/05/2010 22:39:57

@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.

 Ajouter un commentaire




Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

Photothèque

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 1,217 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales