[Windowseries] Mutex...

Mutex... [Windowseries] - C++ - Programmation

Marsh Posté le 07-08-2003 à 12:29:43    

Une question : Considerons le code ci dessous avec le mutex g_hMutex de creer. A ce que j'ai compris, dans le cas ou plusieurs threads s'executent, chacun s'execute a un instant precis d'une duree aleatoire.
Ainsi supposons que dans la boucle infini ci dessous, a un certain moment, ce thread est actif 1 seconde ; le thread s'execute, relache le jeton puis tout de suite reprend le jeton...comment les autres threads font pour avoir le jeton pile poil au moment au le thread le relache parce que si a ce moment ou le jeton est relache les autres threads ne s'execute pas, le thread qui a libere le jeton le reprend aussitot non ?  
 
Une autre question : mes threads s'execute dans differents fichier. Pour que chacun puis acceder au Mutex, je suis oblige de passer par une variable globale ?    (puis de faire des extern)
 
Encore une autre question : Supposons deux fonctions A et B executees chacune par un thread (multithreading). La fonction A doit remplir un Buffer. La fonction B doit lire le buffer APRES qu'il ait ete rempli par la fonction A. Au moment ou l'on rentre dans l'une des fonctions, un mutex (jeton) est capture puis libere juste celu ci a la fin de la fonction. Ensuite la fonction B peut s'executer. Cependant qu'est ce qui me garantie que c la fonction A qui sera la 1ere a obtenir le jeton et pas la fonction B au lancement du programme ? :/
 
Code :
 

Code :
  1. for (;;)
  2.        {
  3.            __try
  4.             {
  5.                  // Obtenir le jeton
  6.                  WaitForSingleObject(g_hMutex,INFINITE) ;
  7.                  if (g_dwTemperature <= 70)
  8.                   {
  9.                       // L'eau n'est pas trop chaude
  10.                       LaverLinge(); // durée : 30 min
  11.                   }
  12.             }
  13.            __finally
  14.             {
  15.                  // Rendre le jeton après que la lessive soit terminée
  16.                  ReleaseMutex(g_hMutex);
  17.              }
  18.        }


Message édité par Giz le 08-08-2003 à 11:21:42
Reply

Marsh Posté le 07-08-2003 à 12:29:43   

Reply

Marsh Posté le 07-08-2003 à 13:17:07    

Ben ... Pour Windows, tu peux faire un Sleep(0); après avoir relâché le mutex pour laisser d'autres processus prendre la main ... Attention, c'est pas portable, hein ? C'est juste pour Win ...


---------------
last.fm
Reply

Marsh Posté le 07-08-2003 à 13:39:09    


Ainsi supposons que dans la boucle infini ci dessous, a un certain moment, ce thread est actif 1 seconde ; le thread s'execute, relache le jeton puis tout de suite reprend le jeton...comment les autres threads font pour avoir le jeton pile poil au moment au le thread le relache parce que si a ce moment ou le jeton est relache les autres threads ne s'execute pas, le thread qui a libere le jeton le reprend aussitot non ?
 
Je pense que tu n'as pas bien compris comment on utilise les mutex avec les thread.
 

Code :
  1. Algo de base :
  2. while( true)
  3. {
  4.    WaitForSingleObject(mutex)
  5.    /*** ce qui doit être fait***/
  6.    ReleaseMutex(mutex);
  7. }


 
Cette boucle doit se trouver dans tous les thread qui utilisent le mutex. Chaque thread se retrouve bloqué par WaitForSingleObject jusqu'a ce que le mutex soit libéré. Des que un des thread libère le mutex la boucle du thread bloqué reprend.
Si plusieurs thread attendent un mutex je pense qu'il y une gestion de file d'attente ( à confirmer)
 
 
Une autre question : mes threads s'execute dans differents fichier. Pour que chacun puis acceder au Mutex, je suis oblige de passer par une variable globale ?    (puis de faire des extern)
Tu parles de fichiers sources ?
 
 
 
 

Reply

Marsh Posté le 07-08-2003 à 14:36:02    

y a pas de fonction yield sous windows?

Reply

Marsh Posté le 07-08-2003 à 14:40:10    

Taz a écrit :

y a pas de fonction yield sous windows?


 
Ca dépend elle fait quoi cette fonction, c celle qui dit qu'un trhead peut être intérompu non?

Reply

Marsh Posté le 07-08-2003 à 14:48:02    

Bon si non:
 

Citation :


The state of a mutex object is signaled when it is not owned by any thread. The creating thread can use the bInitialOwner flag to request immediate ownership of the mutex. Otherwise, a thread must use one of the wait functions to request ownership. When the mutex's state is signaled, one waiting thread is granted ownership, the mutex's state changes to nonsignaled, and the wait function returns. Only one thread can own a mutex at any given time. The owning thread uses the ReleaseMutex function to release its ownership.


 
A priori je dirais que dès qu'on release un mutex un autre thread en reçoit la propriété  [:spamafote]

Reply

Marsh Posté le 07-08-2003 à 15:14:44    

LetoII a écrit :


 
Ca dépend elle fait quoi cette fonction, c celle qui dit qu'un trhead peut être intérompu non?

non: ca veut dire rendre la main pour son quantum de temps pour que l'ordonnanceur puisse immédiatement lancer un autre thread.

Reply

Marsh Posté le 07-08-2003 à 15:18:27    

Taz a écrit :

non: ca veut dire rendre la main pour son quantum de temps pour que l'ordonnanceur puisse immédiatement lancer un autre thread.


 
Mouai j'étais pas loin. Ca doit pas exister, mais c à vérifier.

Reply

Marsh Posté le 07-08-2003 à 15:26:50    

seblamb a écrit :


Ainsi supposons que dans la boucle infini ci dessous, a un certain moment, ce thread est actif 1 seconde ; le thread s'execute, relache le jeton puis tout de suite reprend le jeton...comment les autres threads font pour avoir le jeton pile poil au moment au le thread le relache parce que si a ce moment ou le jeton est relache les autres threads ne s'execute pas, le thread qui a libere le jeton le reprend aussitot non ?
 
Je pense que tu n'as pas bien compris comment on utilise les mutex avec les thread.
 

Code :
  1. Algo de base :
  2. while( true)
  3. {
  4.    WaitForSingleObject(mutex)
  5.    /*** ce qui doit être fait***/
  6.    ReleaseMutex(mutex);
  7. }


 
Cette boucle doit se trouver dans tous les thread qui utilisent le mutex. Chaque thread se retrouve bloqué par WaitForSingleObject jusqu'a ce que le mutex soit libéré. Des que un des thread libère le mutex la boucle du thread bloqué reprend.
Si plusieurs thread attendent un mutex je pense qu'il y une gestion de file d'attente ( à confirmer)
 
 
Une autre question : mes threads s'execute dans differents fichier. Pour que chacun puis acceder au Mutex, je suis oblige de passer par une variable globale ?    (puis de faire des extern)
Tu parles de fichiers sources ?
 
 
 
 
 


 
-Voila et cette file d'attente comment elle s'organise ? -> on retombe sur ma question 1 : Est ce qu'un thread qui vient juste de relacher le mutex peut de nouvo etre le premier dans la file d'attente en fait sachant que chaque thread s'execute dans un ordre aleatoire (a confirmer, c la question que je me pose) pendant une duree aleatoire? ... ma question 1 revient a ca en kk sorte.
Est ce qu'au moment ou un mutex est relache, une priorite logique est etablie entre les differents threads qui doivent s'executer a tour de role en requierant le mutex...de facon a ce que ce ne soit pas le thread qui a relache le mutex qui recommence a s'executer.
 
-Oui bien sur je parle des fichiers sources dans lesquels je code.

Reply

Marsh Posté le 07-08-2003 à 15:47:55    

Apparemment c'est bien dans l'ordre d'arrivé.
http://www.roguewave.com/support/d [...] l/8-3.html

Citation :


In Win32, threads that are blocked on a mutex are handled in a first in, first out (FIFO) order; the first to wait on the mutex will be the first to receive the mutex, regardless of thread priority.
 
There is an exception to this rule; Windows NT can interrupt a waiting thread, resulting in a change in the wait order. A kernel-mode asynchronous procedure call (APC) can interrupt a user-mode thread's execution at any time. Once the normal execution of the thread resumes, the thread will again wait on the mutex; however, the thread is placed at the end of the wait queue.  
 
An example of this behavior can be found each time you encounter a debug breakpoint. The breakpoint forces entry into the debugger, which immediately suspends all threads, forcing them to exit any mutex waits so they can run a piece of kernel-mode code. When you continue from the debugger, the suspended threads are resumed, causing them to reenter their wait for the mutex, but possibly in a different order than before. Therefore, when the synchronization process is viewed from the debugger, it may not appear as though the mutex is acquired in FIFO order. This behavior may cause synchronization problems, such as priority inversion, to appear when running under the debugger, but not in normal execution.
 
This implementation detail applies only to Windows NT. Windows 95 and other platforms that support the Win32 API may use different strategies.
 
Most programs will not need to worry about this behavior. Only those applications that might experience priority inversion need consider this behavior.


 
Il ne doit y avoir qu'une seul mutex par thread ( resultat de CreateMutex ou OpenMutex ), donc en C on peut utiliser une variable globale , en C++ c'est surement pas la meilleur solution


Message édité par seblamb le 07-08-2003 à 15:49:44
Reply

Marsh Posté le 07-08-2003 à 15:47:55   

Reply

Marsh Posté le 07-08-2003 à 16:08:41    

Taz a écrit :

y a pas de fonction yield sous windows?


 
Vous écoutez ce que je dis ?
 

Citation :


Remarks
This function causes a thread to relinquish the remainder of its time slice and become unrunnable for at least the specified number of milliseconds, after which the thread is ready to run. In particular, if you specify zero milliseconds, the thread will relinquish the remainder of its time slice but remain ready. Note that a ready thread is not guaranteed to run immediately. Consequently, the thread may not run until some time after the specified interval elapses. For more information, see Scheduling Priorities.


Message édité par theShockWave le 07-08-2003 à 16:09:41

---------------
last.fm
Reply

Marsh Posté le 07-08-2003 à 16:09:32    

theShOcKwAvE a écrit :


 
Vous écoutez ce que je dis ?


 
Spas tt à fait la même chose.

Reply

Marsh Posté le 07-08-2003 à 16:10:11    

LetoII a écrit :


 
Spas tt à fait la même chose.


 
si :o


---------------
last.fm
Reply

Marsh Posté le 07-08-2003 à 16:11:13    


 
Nan tu fais une utilisation détournée d'une fonction pour émuler un autre comportement ;)


Message édité par LetoII le 07-08-2003 à 16:11:56
Reply

Marsh Posté le 07-08-2003 à 16:13:36    

LetoII a écrit :


 
Nan tu fais une utilisation détournée d'une fonction pour émuler un autre comportement ;)


 
je pense qu'on peut se le permettre qd c'est clairement expliqué dans la doc, quand même ... :D


---------------
last.fm
Reply

Marsh Posté le 07-08-2003 à 16:16:18    

theShOcKwAvE a écrit :


 
je pense qu'on peut se le permettre qd c'est clairement expliqué dans la doc, quand même ... :D


 
J'ai jamais dit qu'on pouvais pas le faire :D

Reply

Marsh Posté le 07-08-2003 à 16:23:06    

seblamb a écrit :

Apparemment c'est bien dans l'ordre d'arrivé.
http://www.roguewave.com/support/d [...] l/8-3.html

Citation :


In Win32, threads that are blocked on a mutex are handled in a first in, first out (FIFO) order; the first to wait on the mutex will be the first to receive the mutex, regardless of thread priority.
 
There is an exception to this rule; Windows NT can interrupt a waiting thread, resulting in a change in the wait order. A kernel-mode asynchronous procedure call (APC) can interrupt a user-mode thread's execution at any time. Once the normal execution of the thread resumes, the thread will again wait on the mutex; however, the thread is placed at the end of the wait queue.  
 
An example of this behavior can be found each time you encounter a debug breakpoint. The breakpoint forces entry into the debugger, which immediately suspends all threads, forcing them to exit any mutex waits so they can run a piece of kernel-mode code. When you continue from the debugger, the suspended threads are resumed, causing them to reenter their wait for the mutex, but possibly in a different order than before. Therefore, when the synchronization process is viewed from the debugger, it may not appear as though the mutex is acquired in FIFO order. This behavior may cause synchronization problems, such as priority inversion, to appear when running under the debugger, but not in normal execution.
 
This implementation detail applies only to Windows NT. Windows 95 and other platforms that support the Win32 API may use different strategies.
 
Most programs will not need to worry about this behavior. Only those applications that might experience priority inversion need consider this behavior.


 
Il ne doit y avoir qu'une seul mutex par thread ( resultat de CreateMutex ou OpenMutex ), donc en C on peut utiliser une variable globale , en C++ c'est surement pas la meilleur solution


 
-Parfait t'a citation, ca repond pile poil a ma premiere question  :jap: J'ai compris que c t une methode FIFO des threads qui e t employe. Donc au moment ou un mutex est relache, c le prochain thread dans la liste d'attente qui demande le mutex qui est execute.
 
-Pour la 2eme question. J'ai utilise en 1er lieu une variable globale :/. Que propose tu comme idee pour mon prog en C++ (les diff threads sont dans diff .cpp) pour que le utex soit visible par tout les threads
 
-J'attends la reponse a la 3eme question ;).

Reply

Marsh Posté le 07-08-2003 à 16:52:59    

Pour la 2eme question, je propose d'ajouter un parametre a chaque fonction executee par mes threads. Ce parametre est donc le buffer dans le chaque threads ecrira/lira...c mieux ca ?

Reply

Marsh Posté le 07-08-2003 à 17:05:51    

LetoII a écrit :


 
Nan tu fais une utilisation détournée d'une fonction pour émuler un autre comportement ;)


 
Nop c l implementation de Win32, Sleep(0) = yield
 
Sinon y a qu a utiliser lib pThred et tu a le yield (qui fait un sleep(0))

Reply

Marsh Posté le 07-08-2003 à 17:09:15    

giz a écrit :

Pour la 2eme question, je propose d'ajouter un parametre a chaque fonction executee par mes threads. Ce parametre est donc le buffer dans le chaque threads ecrira/lira...c mieux ca ?


 
Ca serait quand mm plus propre d avoir tes thread membre du mm objet, a la creation de passe pointeur sur l ojbet carrement.
 
Mutex = membre de l objet
Buffer = membre de l objet
 
Tout le monde peut utilser la mutex/semaphore/autre pour acceder au buffer

Reply

Marsh Posté le 07-08-2003 à 17:13:00    

VisualC++ a écrit :


 
Ca serait quand mm plus propre d avoir tes thread membre du mm objet, a la creation de passe pointeur sur l ojbet carrement.
 
Mutex = membre de l objet
Buffer = membre de l objet
 
Tout le monde peut utilser la mutex/semaphore/autre pour acceder au buffer


 
Tu veux donc carrement creer une classe "CThread" qui contiendrait un mutex et une fonction de creation de Buffer (un tableau de buffer)?  :heink:

Reply

Marsh Posté le 07-08-2003 à 17:15:46    

une classe celle que tu as deja, et qui elle fait les beginthread sur des fonctions a elle et qui a ds ses membres ta mutex et ton buff

Reply

Marsh Posté le 07-08-2003 à 17:36:01    

VisualC++ a écrit :

une classe celle que tu as deja, et qui elle fait les beginthread sur des fonctions a elle et qui a ds ses membres ta mutex et ton buff


 
OK j'ai compris  :jap: : toutes les classes contenant des fonctions executees par un thread doivent avoir en donnees membres le buffer + mutex :).
Etant donne qu'un mutex est sollicite par au moins 2 threads; imaginons que chacun de ces threads execute une fonction appartenant a une classe differente...ces 2 threads etant lies par le mutex, ces classes executeront la fonction "threade" qui devra alors prendre en argument le mutex de l'autre classe ? c propre ca ?  :heink:


Message édité par Giz le 07-08-2003 à 17:37:11
Reply

Marsh Posté le 07-08-2003 à 20:57:48    

Un mutex est unique au niveau du systeme d'exploitation
Mais par contre tu peux récupérer plusieurs handle de mutex qui pointe sur un seul mutex
 

Code :
  1. HANDLE mutex1 = CreateMutex(NULL, FALSE, "MON_MUTEX);
  2. HANDLE mutex2 = CreateMutex(NULL, FALSE, "MON_MUTEX);


 
Dans cet example je crée deux handle de mutex mais un seul mutex.
Et je peux alors les utiliser chacun dans un thread.
 
Deux choix pour stocker ce handle:  
 Il est appelé très souvant -> au niveau de la class dans laquelle sont la ou les fonctions qui utilisent ce thread ( le CreateMutex est alors au niveau du constructeur
 Il est appelé rarement -> directement dans la fonction qui utilise le mutex en faisant un CreateMutex au début de la fonction.
 
Une autre solution encore plus "objet" est de créer autour de ce qui est à protéger ( pas ex un buffer ) une class avec des fonction d'écriture et de lecture sur ce buffer qui utiliseront les mutex. Chaque classe qui utilise ce buffer utilisera à la place une instance de cette nouvelle classe pour lire et écrite.
 
En voici l'idée générale

Code :
  1. class ProtegeBuf
  2. {
  3.    BYTE *m_buffer;
  4.    HANDLE m_mutex;
  5. public :
  6.    ProtegeBuf(BYTE *buf);
  7.    void Write( BYTE *data);
  8. };
  9. ProtegeBuf::ProtegeBuf( BYTE *buf): m_buffer(buf)
  10. {
  11. m_mutex = CreateMutex(NULL, FALSE, "MON_MUTEX" );
  12. }
  13. void ProtegeBuf::Write( BYTE *data)
  14. {
  15. WaitForSingleObject(m_mutex, INFINITE);
  16. memcpy( m_buffer, data, 30);
  17. ReleaseMutex( m_mutex);
  18. }

Reply

Marsh Posté le 08-08-2003 à 11:20:51    

OK merci  :jap:  
 
et pour la 3eme question ? une idee  :??:

Reply

Marsh Posté le 08-08-2003 à 11:22:13    

giz a écrit :

OK merci  :jap:  
 
et pour la 3eme question ? une idee  :??:  


 
C à toi de faire en sorte que tes méthodes n'accédent pas n'importe comment à la chose, par exmple B peut vérifier qu'il y a qqc d'écrit avant de lire.

Reply

Marsh Posté le 08-08-2003 à 11:38:54    

Bon, je crois que je vais avoir besoin de mutex aussi, je me permets donc de m'incruster dans ce topic...
En ce qui me concerne, c'est l'accès à une bdd (utilisation d'une CDatabase avec ODBC dans une classe dédiée) que je souhaiterais controler.
Le problème est que je vais accéder à cette bdd non seulement via plusieurs threads, mais surtout via plusieurs applis différentes, dont une qui sera instanciée plusieurs fois...
Est-ce que le problème est toujours le même?

Reply

Marsh Posté le 08-08-2003 à 11:40:28    

skeye a écrit :

Bon, je crois que je vais avoir besoin de mutex aussi, je me permets donc de m'incruster dans ce topic...
En ce qui me concerne, c'est l'accès à une bdd (utilisation d'une CDatabase avec ODBC dans une classe dédiée) que je souhaiterais controler.
Le problème est que je vais accéder à cette bdd non seulement via plusieurs threads, mais surtout via plusieurs applis différentes, dont une qui sera instanciée plusieurs fois...
Est-ce que le problème est toujours le même?


 
Oui, les mutex peuvent aussi servir à la synchro inter-process


Message édité par LetoII le 08-08-2003 à 11:40:38
Reply

Marsh Posté le 08-08-2003 à 11:47:57    

LetoII a écrit :


 
Oui, les mutex peuvent aussi servir à la synchro inter-process


Donc, si je crée mon mutex dans la classe qui gère la bdd et que je l'utilise dans les fonctions membres de cette même classe, pas de pbs entre les process différents?!

Reply

Marsh Posté le 08-08-2003 à 15:35:49    

seblamb a écrit :

Un mutex est unique au niveau du systeme d'exploitation
Mais par contre tu peux récupérer plusieurs handle de mutex qui pointe sur un seul mutex
 

Code :
  1. HANDLE mutex1 = CreateMutex(NULL, FALSE, "MON_MUTEX);
  2. HANDLE mutex2 = CreateMutex(NULL, FALSE, "MON_MUTEX);


 
Dans cet example je crée deux handle de mutex mais un seul mutex.
Et je peux alors les utiliser chacun dans un thread.
 
Deux choix pour stocker ce handle:  
 Il est appelé très souvant -> au niveau de la class dans laquelle sont la ou les fonctions qui utilisent ce thread ( le CreateMutex est alors au niveau du constructeur
 Il est appelé rarement -> directement dans la fonction qui utilise le mutex en faisant un CreateMutex au début de la fonction.
 
Une autre solution encore plus "objet" est de créer autour de ce qui est à protéger ( pas ex un buffer ) une class avec des fonction d'écriture et de lecture sur ce buffer qui utiliseront les mutex. Chaque classe qui utilise ce buffer utilisera à la place une instance de cette nouvelle classe pour lire et écrite.
 
En voici l'idée générale

Code :
  1. class ProtegeBuf
  2. {
  3.    BYTE *m_buffer;
  4.    HANDLE m_mutex;
  5. public :
  6.    ProtegeBuf(BYTE *buf);
  7.    void Write( BYTE *data);
  8. };
  9. ProtegeBuf::ProtegeBuf( BYTE *buf): m_buffer(buf)
  10. {
  11. m_mutex = CreateMutex(NULL, FALSE, "MON_MUTEX" );
  12. }
  13. void ProtegeBuf::Write( BYTE *data)
  14. {
  15. WaitForSingleObject(m_mutex, INFINITE);
  16. memcpy( m_buffer, data, 30);
  17. ReleaseMutex( m_mutex);
  18. }




 
Et pour que l'instance soit utilisee par plusieurs classes (plusieurs fichier .cpp plus exactement) comment je fais ? :/ ... je declare cette instance en variable globale ?  :(  
 
En fait j'ai du mal a voir comment je peut eviter cette variable globale :/ : je pensait au fait de creer une classe qui contiendra seulement un objet protegebuf, et les classes qui en ont besoin ensemble pourront y acceder du fait que j'integrerai cette classe, contenant seulement un objet protegebuf, dans les classes qui l'utiliseront ensemble (principe d'heritage).
En fait, grosso modo ca revient a dire qu'une paire de classe (2 classe) partageront un meme objet protegebuf ; cette objet etant issu d'une "classe de base" contenant ce seul objet protegebuf. Mais bon, j'ai environ 3 pair de classes qui doivent se partager une instance protegebuf...cela implique la creation de trois classe differentes contenant seulement un objet protegebuf :/ ... ce qui est tres porc...tout ca juste pour eviter les variables globale !
bref je ne sais pas trop koi faire  :(

Reply

Marsh Posté le 08-08-2003 à 17:26:13    

Un autre truc : voici le prototype de la fonction CreateMutex (VC++6)  
 

Code :
  1. HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCTSTR lpName );


Ca sert a koi de donner un nom au mutex (3eme parametre) ? : le handle que l'on recupere suffit a identifier le mutex non ? :/


Message édité par Giz le 08-08-2003 à 17:27:34
Reply

Marsh Posté le 08-08-2003 à 17:39:06    

Faudrait lire un peu la programation multithread et ca sert de lire les man .....
 


lpName  
[in] Pointer to a null-terminated string specifying the name of the mutex object. The name is limited to MAX_PATH characters. Name comparison is case sensitive.  
If lpName matches the name of an existing named mutex object, this function requests MUTEX_ALL_ACCESS access to the existing object. In this case, the bInitialOwner parameter is ignored because it has already been set by the creating process. If the lpMutexAttributes parameter is not NULL, it determines whether the handle can be inherited, but its security-descriptor member is ignored.  
 
If lpName is NULL, the mutex object is created without a name.  
 
If lpName matches the name of an existing event, semaphore, waitable timer, job, or file-mapping object, the function fails and the GetLastError function returns ERROR_INVALID_HANDLE. This occurs because these objects share the same name space.  
 
Terminal Services: The name can have a "Global\" or "Local\" prefix to explicitly create the object in the global or session name space. The remainder of the name can contain any character except the backslash character (\). For more information, see Kernel Object Name Spaces.  
 
Windows XP: Fast user switching is implemented using Terminal Services sessions. The first user to log on uses session 0, the next user to log on uses session 1, and so on. Kernel object names must follow the guidelines outlined for Terminal Services so that applications can support multiple users.  
 
Windows 2000: If Terminal Services is not running, the "Global\" and "Local\" prefixes are ignored. The remainder of the name can contain any character except the backslash character.  
 
Windows NT 4.0 and earlier: The name can contain any character except the backslash character.  
 
Windows 95/98/Me: The name can contain any character except the backslash character. The empty string ("" ) is a valid object name.  
 

Reply

Marsh Posté le 20-08-2003 à 16:56:25    

Code :
  1. void NetSs2ig(void *pvoid)
  2. {
  3. /* Retrieve the CNet_comm object */
  4. CNet_comm *net_ss2ig = (CNet_comm *) (pvoid);
  5. if (net_ss2ig == NULL) {
  6.  printf("Error executing thread net_ss2ig...exiting thread" );
  7.  return;
  8. }
  9. /* Code executed by thread */
  10.  //UDP connection
  11. net_ss2ig->Init_Socket(0);
  12. net_ss2ig->Send_UDP_Packets();
  13. _endthread();
  14. }


 
dans mon main.cpp je lance un thread via _beginthread. Il execute la finction ci-dessus. Pour pas que mon main se finisse, il est en attente d'appui sur une touche (thread qui s'execute tant qu'aucune touche a ete appuye, sinon, le main se termine et donc fin du programme et de tous les threads lance ds le prog).
En executant ce seul thread (+ celui qui attends que j'appuie sur une touche pour finir le main()), lorsque j'appuie sur une touche, j'ai la fenetre "fermer/detail" d'erreur windows :/ en clair mon programme se termine mal  :sweat:  
a v vous une idee d'ou cela vient ?
Je sais que c juste ce thread lance au dessus qui fait merder car c la seul chose qui tourne ds le prog ! le thread qui permet de finir le main() marche bien (c celui de la msdn en plus :D)
PS : si vous voulez le code de la fonction net_ss2ig->Send_UDP_Packets() dite moi le : elle contient la boucle infini qui envoit des packets UDP c tout .
 
thx


Message édité par Giz le 20-08-2003 à 16:58:11
Reply

Marsh Posté le 20-08-2003 à 17:10:47    

situation classique : ton thread se sert d'objets créés dans ton main, et lorsque ton prog quittes, ces objets sont détruits mais il est possible que ton thread tourne toujours, et se sert donc de variables qui n'existent plus => crash.
 
pour cela, quitte ton thread proprement a la fin de ton prog. Un simple TerminateThread devrait aussi faire l'affaire, mais c'est deja plus crade...

Reply

Marsh Posté le 21-08-2003 à 10:46:34    

Konar a écrit :

situation classique : ton thread se sert d'objets créés dans ton main, et lorsque ton prog quittes, ces objets sont détruits mais il est possible que ton thread tourne toujours, et se sert donc de variables qui n'existent plus => crash.
 
pour cela, quitte ton thread proprement a la fin de ton prog. Un simple TerminateThread devrait aussi faire l'affaire, mais c'est deja plus crade...


 
+1
 
C exactement l'erreur que j'ai (j'ai trouve juste avt de partir en changeant la valeur de repeat par le debuggeur)
Merci  [:giz]

Reply

Marsh Posté le 21-08-2003 à 12:32:48    

wé et si tu maintiens la liste de threads dans un tableau,
 
avec un WaitFormultipleobjets tu peux attendre la fin du thread...
 

Code :
  1. HANDLE hTh[3];
  2. hTh[0]=CreateThread(....
  3. hTh[1]=CreateThread(....
  4. hTh[2]=CreateThread(....
  5. // fin du main général
  6. // attente fin de vie des threads (les 3 simultanés)
  7. WaitForMultipleObjects(3,hTh,true,INFINITE);
  8. // fermeture des handles de threads
  9. CloseHandle(hTh[0]);
  10. CloseHandle(hTh[1]);
  11. CloseHandle(hTh[2]);

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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