Thread

cs_elbok Messages postés 12 Date d'inscription mardi 4 mars 2008 Statut Membre Dernière intervention 28 avril 2008 - 26 avril 2008 à 10:41
BruNews Messages postés 21041 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019 - 28 avril 2008 à 17:42
salut pour tous
j'ai besoin de créer un thread qui exécutera un fonction de prototype: void traitement (struct liste *l).
je suis vraiment débutanant et je veux savoir comment créer le thread qui exécute cette fonction chaque 2 secondes, comment lui passer le paramètre struct list *l de la fonction et quelle est la bibliothèque correspondante?
si vous pouvez m'expliquez avec des exemples alors je vous remerçi fortement.
j'utiulise vvisual C++ mais j'écris en C, je travail sur une console Win32. os : windows.
S.V.P aidez moi c'est trés trés  urgent!!!
merçi d'avance.

8 réponses

BruNews Messages postés 21041 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
26 avril 2008 à 11:05
void traitement(struct liste *l);
à changer en:
DWORD __stdcall traitement(LPVOID pl);
dedans tu feras le cast de pl en liste*, voila tout.


APPEL:
hthrd = CreateThread(0, 0, traitement, (void*) taliste, 0, 0);

ciao...
BruNews, MVP VC++
0
cs_jfrancois Messages postés 482 Date d'inscription vendredi 26 août 2005 Statut Membre Dernière intervention 5 décembre 2009 2
26 avril 2008 à 11:26
Bonjour,

Voilà un exemple de thread sous console :

#include <stdio.h>
#include <conio.h> // pour getch()
#include <time.h>  // pour time()
#include <windows.h>




// --- La liste à manipuler
struct LISTE
{
   int a;
   int b;
   int c;
};






// ------------------------------
// Thread réalisant le traitement
// (boucle toutes les 2 secondes)
// ------------------------------
DWORD WINAPI Traitement
(
   LPVOID pData // E:pointe les données
)               // S:code retour
{
   while (true)
   {
      // --- "cast" de l'adresse passée
      LISTE* pListe = (LISTE*)pData;

      // --- Visu de l'horloge et de la liste
      printf("time=%ld a=%d b=%d c=%d\n"
            ,time(NULL)
            ,pListe->a,pListe->b,pListe->c);



      // --- Attendre 2 secondes
      Sleep(2000);
   }
   return 0;
}





// -------------------
// Fonction principale
// -------------------
int main(void)
{
   LISTE Liste = {1,2,3};
   DWORD dwThreadID;




   printf("Debut\n");


   // --- Lancer le thread
   if (CreateThread(NULL,0,Traitement,(LPVOID)&Liste,0,&dwThreadID) == NULL)
   {
      // --- Erreur
      printf("ERREUR A LA CREATION DU THREAD\n");
   }
   else
   {
      // --- Attente de 5s puis modif de la liste pour voir !
      Sleep(5000);
      Liste.a = 10;
      Liste.b = 20;
      Liste.c = 30;
     
      // --- Attente de la frappe d'une touche pour tout quitter
      // --- (le thread s'arrête avec le programme)
      getch();
   }
   printf("Fin\n");
   return 0;
}




Ce qui donne :

Debut
time=1209201543 a=1 b=2 c=3    <-- Lancement H0
time=1209201545 a=1 b=2 c=3    <-- H0 + 2s
time=1209201547 a=1 b=2 c=3    <-- H0 + 4s
Modif de la liste              <-- H0 + 5s
time=1209201549 a=10 b=20 c=30 <-- H0 + 6s
time=1209201551 a=10 b=20 c=30 <-- H0 + 8s
time=1209201553 a=10 b=20 c=30 <-- H0 + 10s
time=1209201555 a=10 b=20 c=30 <-- H0 + 12s
time=1209201557 a=10 b=20 c=30 <-- Appui sur une touche
Fin

Jean-François
0
cs_elbok Messages postés 12 Date d'inscription mardi 4 mars 2008 Statut Membre Dernière intervention 28 avril 2008
26 avril 2008 à 18:42
Salut


mais non c'est pas ça, j'ai essayer avec les thread Posix mais j'ai eu un grand problème avec la bibliothèquemalgrés que je l'ais télécharger et je l'ai installé.
en tout cas je remerçis bien tout ceux qui m'ont aidé vous êtes vraiment trés gentils
0
cs_elbok Messages postés 12 Date d'inscription mardi 4 mars 2008 Statut Membre Dernière intervention 28 avril 2008
26 avril 2008 à 18:46
je vous remerçis vraiment je vais essayer ce que vous m'avez écris et je vous informe dans tous les cas du résultat malgrés que je pense que ce bout de code que vous m'avez envoyé va m'aider et me permettre de résoudre mon problème avec les threads.


merçi bien bien.


à+
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_elbok Messages postés 12 Date d'inscription mardi 4 mars 2008 Statut Membre Dernière intervention 28 avril 2008
28 avril 2008 à 09:22
salut pour tous<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /??>





j'ai un problème avec les threads





soit le bout de code suivant:





int main(void)





{





DWORD dwThreadID;





struct liste_bok *liste;






 






Create(liste);// cette fonction permet de créer une liste en  associant à ses champs des valeurs initiaux qui vont être modifiés par la suite par 2 threads






 






// création de 2 threads






 






if (CreateThread(NULL,0, traitement1,(LPVOID)liste,0,&dwThreadID) == NULL)





{





// --- Erreur





printf("ERREUR A LA CREATION DU THREAD traitement 1\n");





}






 






// Ici je veux lancer un deuxième thread qui prend à chaque fois comme paramètre la listequi a était modifié par le thread de la fonction traitement1





// alors j'ai procédé comme suit






 






// --- Lancer le thread de pre_scan





if (CreateThread(NULL,0,traitement2,(LPVOID)liste,0,&dwThreadID) == NULL)





{





// --- Erreur





printf("ERREUR A LA CREATION DU THREAD traitement 2\n");





}





getch();





return 0;





}






 






la création des deux thréad a réussit sauf que je pense que le thread de la fonction traitement2 ne prend pas le paramètre "liste" aprés





modification de la part du thread de la fonction traitement1 mais il prend la liste initiale qui a été créée par la fonction create(liste)





je ne sais pas si j'avais raison ou non.





si oui alors S.V.P pouvez vous m'indiquer une solution pour passer au second thread (thread de la fonction traitement2) le paramètre liste






 aprés modification de la part du thread de la fonction traitement1.





merçi d'avance.
0
cs_jfrancois Messages postés 482 Date d'inscription vendredi 26 août 2005 Statut Membre Dernière intervention 5 décembre 2009 2
28 avril 2008 à 14:29
Bonjour,

En reprenant l'exemple que je vous avais passé et en ajoutant un second thread qui modifie la liste, tout fonctionne correctement (a priori ! voir plus bas) : Le premier thread modifie la liste toutes les 2 secondes et le second thread l'affiche toutes les secondes.

Donc en ce qui vous concerne, il faudrait savoir comment est utilisé le pointeur "liste" dans les 2 fonctions de traitement pour voir pourquoi les modifications ne sont pas prises en compte !

Voilà le code que cela donne, dans un premier temps :

#include <stdio.h>
#include <conio.h>
#include <time.h>
#include <windows.h>




// --- Horloge initiale pour chronométrer
static time_t g_tH0 = time(NULL);




// --- La liste à manipuler
struct LISTE
{
   int a;
   int b;
   int c;
};






// --------------------------------
// Thread réalisant le traitement 1
// Modifier la liste
// --------------------------------
DWORD WINAPI Traitement1
(
   LPVOID pData // E:pointe les données
)               // S:code retour
{
   // --- "cast" de l'adresse passée
   LISTE* pListe = (LISTE*)pData;



   // --- Boucle du traitement
   // --- (tempo avant le traitement)
   while (true)
   {
      // --- Attendre 2s
      Sleep(2000);



      // --- Afficher le chronomètre
      printf("Traitement1 : time=%03ld --> Modifier la liste\n"
            ,time(NULL) - g_tH0);



      // --- Modifier la liste
      pListe->a += 1;
      pListe->b += 1;
      pListe->c += 1;
   }
   return 0;
}





// --------------------------------
// Thread réalisant le traitement 2
// Afficher la liste
// --------------------------------
DWORD WINAPI Traitement2
(
   LPVOID pData // E:pointe les données
)               // S:code retour
{
   // --- "cast" de l'adresse passée
   LISTE* pListe = (LISTE*)pData;



   // --- Boucle du traitement
   // --- (tempo après le traitement)
   while (true)
   {
      // --- Afficher le chronomètre et la liste
      printf("Traitement2 : time=%03ld a=%d b=%d c=%d\n"
            ,time(NULL) - g_tH0
            ,pListe->a,pListe->b,pListe->c);



      // --- Attendre 1s
      Sleep(1000);
   }
   return 0;
}





// -------------------
// Fonction principale
// -------------------
int main(void)
{
   LISTE Liste = {100,200,300};
   DWORD dwThreadID;


   printf("Debut\n");



   // --- Lancer les threads
   HANDLE hThread1 = CreateThread(NULL,0,Traitement1,(LPVOID)&Liste,0,&dwThreadID);
   if (hThread1 == NULL)
   {
      printf("Erreur a la creation du thread Traitement1\n");
      return 0;
   }
   HANDLE hThread2 = CreateThread(NULL,0,Traitement2,(LPVOID)&Liste,0,&dwThreadID);
   if (hThread2 == NULL)
   {
      printf("Erreur a la creation du thread Traitement2\n");
      CloseHandle(hThread1);
      return 0;
   }
     
   // --- Attendre la frappe d'une touche pour quitter
   // --- (les threads tournent pendant ce temps là !)
   getch();



   // --- Fermer les threads
   CloseHandle(hThread1);
   CloseHandle(hThread2);


   printf("Fin\n");
   return 0;
}





Ce qui donne :

Debut
Traitement2 : time=000 a=100 b=200 c=300
Traitement2 : time=001 a=100 b=200 c=300
Traaitmenmmen nt1 =:  time=me=020022  --> Modifier la liste
1Traaitmenmmen nt1 =:  time=me=020022  --> Modifier la liste
100 b=200 c=300
Traitement2 : time=003 a=101 b=201 c=301
Traaiiteemeent12:: tme=me=00044 0a-=-> Modifier la liste
Traaiiteemeent12:: tme=me=00044 0a-=-> Modifier la liste
101 b=201 c=301
Traitement2 : time=005 a=102 b=202 c=302
Traitetement1 : :eimt=ime=00066 a=--> Modifier la liste
10Traitetement1 : :eimt=ime=00066 a=--> Modifier la liste
102 b=202 c=302
Traitement2 : time=007 a=103 b=203 c=303
Traitement1 : time=008 --> Modifier la liste
raitement2 : time=008 a=103 b=203 c=303
Traitement2 : time=009 a=104 b=204 c=304
Traitement1 : time=010 --> Modifier la liste
Traitement2 : time=010 a=105 b=205 c=305
...
Traitement2 : time=095 a=147 b=247 c=347
Traitement1 : time=096 --> Modifier la liste
Traitement2 : time=096 a=148 b=248 c=348
Traitement2 : time=097 a=148 b=248 c=348
Traitement2 : time=098 a=148 b=248 c=348
Traitement2 : time=098 a=148 b=248 c=348
Traitement1 : time=098 --> Modifier la liste
Traitement2 : time=099 a=149 b=249 c=349
Trrraitemeent21 : tmme=10100 -==-> Modifier la liste
149 b=249 c=349
Trrraitemeent21 : tmme=10100 -==-> Modifier la liste
1Traitement2 : time=101 a=150 b=250 c=350
Traitement1 : time=102 --> Modifier la liste
Traitement1 : time=102 --> Modifier la liste
Traitement2 : time=102 a=150 b=250 c=350
Traitement2 : time=103 a=151 b=251 c=351
Traitement2 : time=104 a=151 b=251 c=351
Traitement2 : time=104 a=151 b=251 c=351
Traitement1 : time=104 --> Modifier la liste
Traitement2 : time=105 a=152 b=252 c=352
Trraitemmennt ::tiime=me=150606  =--> Modifier la liste
152 b=252 c=352
Trraitemmennt ::tiime=me=150606  =--> Modifier la liste
15Traitement2 : time=107 a=153 b=253 c=353
Traitement1 : time=108 --> Modifier la liste
Traitement1 : time=108 --> Modifier la liste
Traitement2 : time=108 a=153 b=253 c=353
Fin

Et là on s'aperçoit qu'il se passe de drôles de choses ! Les 2 threads s'exécutent en même temps, de temps en temps ... et c'est la cacophonie ! d'où la nécessité, dans ce genre de situation (2 threads qui se partagent les mêmes données), d'utiliser un dispositif logiciel qui exclue ces exécutions simultanées. Par exemple en utilisant un MUTEX (= mutual exclusion) qui bloque chaque thread pendant l'exécution de l'autre.
 
Ca donne ça :



#include <stdio.h>
#include <conio.h>
#include <time.h>
#include <windows.h>




// --- Handle du mutex

static HANDLE g_hMutex = NULL;





// --- Horloge initiale pour chronométrer
static time_t g_tH0 = time(NULL);




// --- La liste à manipuler
struct LISTE
{
   int a;
   int b;
   int c;
};






// --------------------------------
// Thread réalisant le traitement 1
// Modifier la liste
// --------------------------------
DWORD WINAPI Traitement1
(
   LPVOID pData // E:pointe les données
)               // S:code retour
{
   // --- "cast" de l'adresse passée
   LISTE* pListe = (LISTE*)pData;



   // --- Boucle du traitement
   // --- (tempo avant le traitement)
   while (true)
   {
      // --- Attendre 2s
      Sleep(2000);



      // --- Attendre le mutex

      if (WaitForSingleObject(g_hMutex,INFINITE) >= 0)
      {

         // --- Afficher le chronomètre
         printf("Traitement1 : time=%03ld --> Modifier la liste\n"
               ,time(NULL) - g_tH0);



         // --- Modifier la liste
         pListe->a += 1;
         pListe->b += 1;
         pListe->c += 1;



         // --- Libérer le mutex

         ReleaseMutex(g_hMutex);
      }
   }
   return 0;
}





// --------------------------------
// Thread réalisant le traitement 2
// Afficher la liste
// --------------------------------
DWORD WINAPI Traitement2
(
   LPVOID pData // E:pointe les données
)               // S:code retour
{
   // --- "cast" de l'adresse passée
   LISTE* pListe = (LISTE*)pData;



   // --- Boucle du traitement
   // --- (tempo après le traitement)
   while (true)
   {
      // --- Attendre le mutex
      if (WaitForSingleObject(g_hMutex,INFINITE) >= 0)
      {
         // --- Afficher le chronomètre et la liste
         printf("Traitement2 : time=%03ld a=%d b=%d c=%d\n"
               ,time(NULL) - g_tH0
               ,pListe->a,pListe->b,pListe->c);



         // --- Libérer le mutex

         ReleaseMutex(g_hMutex);
      }



      // --- Attendre 1s
      Sleep(1000);
   }
   return 0;
}





// -------------------
// Fonction principale
// -------------------
int main(void)
{
   LISTE Liste = {100,200,300};
   DWORD dwThreadID;


   printf("Debut\n");



   // --- Créer le mutex (sans nom)

   g_hMutex = CreateMutex(NULL,FALSE,NULL);
   if (g_hMutex == NULL)
   {
      printf("Erreur a la creation du mutex\n");
      return 0;
   }



   // --- Lancer les threads
   HANDLE hThread1 = CreateThread(NULL,0,Traitement1,(LPVOID)&Liste,0,&dwThreadID);
   if (hThread1 == NULL)
   {
      printf("Erreur a la creation du thread Traitement1\n");
      return 0;
   }
   HANDLE hThread2 = CreateThread(NULL,0,Traitement2,(LPVOID)&Liste,0,&dwThreadID);
   if (hThread2 == NULL)
   {
      printf("Erreur a la creation du thread Traitement2\n");
      CloseHandle(hThread1);
      return 0;
   }
     
   // --- Attendre la frappe d'une touche pour quitter
   // --- (les threads tournent pendant ce temps là !)
   getch();



   // --- Fermer les threads
   CloseHandle(hThread1);
   CloseHandle(hThread2);



   // --- Fermer le mutex

   CloseHandle(g_hMutex);


   printf("Fin\n");
   return 0;
}

Ce qui donne :

Debut
Traitement2 : time=000 a=100 b=200 c=300
Traitement2 : time=001 a=100 b=200 c=300
Traitement1 : time=002 --> Modifier la liste
Traitement2 : time=002 a=101 b=201 c=301
Traitement2 : time=003 a=101 b=201 c=301
Traitement1 : time=004 --> Modifier la liste
Traitement2 : time=004 a=102 b=202 c=302
Traitement2 : time=005 a=102 b=202 c=302
Traitement1 : time=006 --> Modifier la liste
Traitement2 : time=006 a=103 b=203 c=303
Traitement2 : time=007 a=103 b=203 c=303
Traitement1 : time=008 --> Modifier la liste
Traitement2 : time=008 a=104 b=204 c=304
Traitement2 : time=009 a=104 b=204 c=304
Traitement1 : time=010 --> Modifier la liste
Traitement2 : time=010 a=105 b=205 c=305
Traitement2 : time=011 a=105 b=205 c=305
Traitement2 : time=012 a=105 b=205 c=305
Traitement1 : time=012 --> Modifier la liste
...
Traitement2 : time=182 a=190 b=290 c=390
Traitement1 : time=182 --> Modifier la liste
Traitement2 : time=183 a=191 b=291 c=391
Traitement2 : time=184 a=191 b=291 c=391
Traitement1 : time=184 --> Modifier la liste
Traitement2 : time=185 a=192 b=292 c=392
Traitement1 : time=186 --> Modifier la liste
Traitement2 : time=186 a=193 b=293 c=393
Traitement2 : time=187 a=193 b=293 c=393
Traitement1 : time=188 --> Modifier la liste
Traitement2 : time=188 a=194 b=294 c=394
Traitement2 : time=189 a=194 b=294 c=394
Traitement1 : time=190 --> Modifier la liste
Traitement2 : time=190 a=195 b=295 c=395
Traitement2 : time=191 a=195 b=295 c=395
Traitement1 : time=192 --> Modifier la liste
Traitement2 : time=192 a=196 b=296 c=396
Traitement2 : time=193 a=196 b=296 c=396
Traitement1 : time=194 --> Modifier la liste
Traitement2 : time=194 a=197 b=297 c=397
Fin

Plus de problèmes !



Jean-François
0
cs_elbok Messages postés 12 Date d'inscription mardi 4 mars 2008 Statut Membre Dernière intervention 28 avril 2008
28 avril 2008 à 17:12
Salut cher ami Jean François
je voudrais tout dabord vous remercier de votre gentiesse et de votre aide, vous m'avez donnez un bon coup de main à travers vos exemples bien ciblés et pertinant. vraiment vous avez touchez le vrai problème malgrés que je n'ais pas bien expliqué ce qu'il m'a étonné. je crois que la solution des mutex va me donner de bonnes résultats puisque j'ai eux preque le même affichage que vous m'avez envoyé.
en tous cas je vais essayé cette solution et je vais vous informé des résultats.
je vous remerçi encore et à +
elbok 
0
BruNews Messages postés 21041 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
28 avril 2008 à 17:42
Surtout pas de:
if(CreateThread(...


Faut suivre l'exemple de jfrancois, fermer les handles de thread.

ciao...
BruNews, MVP VC++
0