Mutex... [Windowseries] - C++ - Programmation
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 :
|
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 ?
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?
Marsh Posté le 07-08-2003 à 14:48:02
Bon si non:
Citation : |
A priori je dirais que dès qu'on release un mutex un autre thread en reçoit la propriété
Marsh Posté le 07-08-2003 à 15:14:44
LetoII 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.
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.
Marsh Posté le 07-08-2003 à 15:26:50
seblamb a écrit :
|
-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.
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 : |
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
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 : |
Marsh Posté le 07-08-2003 à 16:09:32
ReplyMarsh Posté le 07-08-2003 à 16:10:11
ReplyMarsh Posté le 07-08-2003 à 16:11:13
Nan tu fais une utilisation détournée d'une fonction pour émuler un autre comportement
Marsh Posté le 07-08-2003 à 16:13:36
LetoII a écrit : |
je pense qu'on peut se le permettre qd c'est clairement expliqué dans la doc, quand même ...
Marsh Posté le 07-08-2003 à 16:16:18
theShOcKwAvE a écrit : |
J'ai jamais dit qu'on pouvais pas le faire
Marsh Posté le 07-08-2003 à 16:23:06
seblamb a écrit : Apparemment c'est bien dans l'ordre d'arrivé.
|
-Parfait t'a citation, ca repond pile poil a ma premiere question 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 .
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 ?
Marsh Posté le 07-08-2003 à 17:05:51
LetoII a écrit : |
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))
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
Marsh Posté le 07-08-2003 à 17:13:00
VisualC++ a écrit : |
Tu veux donc carrement creer une classe "CThread" qui contiendrait un mutex et une fonction de creation de Buffer (un tableau de buffer)?
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
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 : 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 ?
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 :
|
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 :
|
Marsh Posté le 08-08-2003 à 11:22:13
giz a écrit : OK merci |
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.
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?
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... |
Oui, les mutex peuvent aussi servir à la synchro inter-process
Marsh Posté le 08-08-2003 à 11:47:57
LetoII a écrit : |
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?!
Marsh Posté le 08-08-2003 à 15:35:49
seblamb a écrit : Un mutex est unique au niveau du systeme d'exploitation
|
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
Marsh Posté le 08-08-2003 à 17:26:13
Un autre truc : voici le prototype de la fonction CreateMutex (VC++6)
Code :
|
Ca sert a koi de donner un nom au mutex (3eme parametre) ? : le handle que l'on recupere suffit a identifier le mutex non ?
Marsh Posté le 08-08-2003 à 17:39:06
Faudrait lire un peu la programation multithread et ca sert de lire les man .....
|
Marsh Posté le 20-08-2003 à 16:56:25
Code :
|
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
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 )
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
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...
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. |
+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
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 :
|
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 :
Message édité par Giz le 08-08-2003 à 11:21:42