Synchronisation de threads en C# - C#/.NET managed - Programmation
Marsh Posté le 28-06-2004 à 09:35:33
oui, y a des primitives pour, mais ça n'est pas vraiment propre. A toi de faire en sorte que ton thread s'arrete tout seul, .Join() le pour attendre sa fin
Marsh Posté le 28-06-2004 à 09:44:09
Taz a écrit : oui, y a des primitives pour, mais ça n'est pas vraiment propre. A toi de faire en sorte que ton thread s'arrete tout seul, .Join() le pour attendre sa fin |
ok merci pour ta reponse, je vais jeter un coup d'oeil a Join
v.
Marsh Posté le 28-06-2004 à 09:44:12
Code :
|
Marsh Posté le 28-06-2004 à 09:47:29
merci pour le bout de code, c'est effectivement ce que j'ai fait.
mon probleme est un peu different (et je doute qu'il y ait une solution ideale).
dans mon main, je lance un thread qui fait une action qui ne se terminera jamais (il boucle et envoit de l'info).
par contre, il se peut que j'aie envie de l'arreter mais apres la fin du main.
je ne suis meme pas sur que ca soit realisable.
v.
Marsh Posté le 28-06-2004 à 09:49:34
il se passe rien après la fin du Main
le problème, il est dans ta tête
Marsh Posté le 28-06-2004 à 09:55:30
Taz a écrit : il se passe rien après la fin du Main |
le thread que j'ai lance tourne toujours non ?
meme apres la fin du main ?
donc ma tete ne va pas si mal que ca !!!
v.
Marsh Posté le 28-06-2004 à 09:56:17
vonm a écrit : |
Marsh Posté le 28-06-2004 à 09:56:56
vonm a écrit : le thread que j'ai lance tourne toujours non ? |
euh, la fin du main signifie la fin du programme et de tous les threads associés hein
Marsh Posté le 28-06-2004 à 09:58:46
Harkonnen a écrit : euh, la fin du main signifie la fin du programme et de tous les threads associés hein |
ben la y'a un truc qui m'echappe parce que ce n'est absolument pas le comportement que je constate.
je comprends pas parce que le thread qui est lance continue alors que je n'ai pas de Join avant la fin de mon main.
est-il possible qu'il en fasse un automatiquement ?
v.
Marsh Posté le 28-06-2004 à 10:07:18
vonm a écrit : ben la y'a un truc qui m'echappe parce que ce n'est absolument pas le comportement que je constate. |
je viens de voir qu'il existe des notions de threads forground et threads background.
peut-etre que mon probleme vient de la, je regarde.
merci pour votre aide
v.
Marsh Posté le 28-06-2004 à 10:35:01
Taz a écrit : les notions ça va te mener loin... |
oh mais merde !
ecoute Taz, t'es bien gentil, tu as essayé de m'aider mais je supporte difficilement ton air supérieur et pédant.
donc, je pense qu'on peut arrêter la, je vais me debrouiller autrement.
v.
Marsh Posté le 28-06-2004 à 10:39:21
tu ferais bien de lire toute la documentation de Thread au lieu de t'énerver, ça te donnera un aperçu de ce que tu peux faire. Après tout ce qui concerne System.Threading.
Mais on a bien compris que tu bricolais jusqu'à que ça marche à peu près
Marsh Posté le 28-06-2004 à 10:43:33
Taz a écrit : tu ferais bien de lire toute la documentation de Thread au lieu de t'énerver, ça te donnera un aperçu de ce que tu peux faire. Après tout ce qui concerne System.Threading. |
oui, tu as raison.
merci pour ton aide precieuse.
le sujet est clos.
v.
Marsh Posté le 28-06-2004 à 13:48:11
En ce qui concerne le code donné par Taz.
Je préfère faire autrement : pour controller l'arret/la pause d'un thread, il vaut mieux utiliser de bons vieux boolean, tout simples, qui effectue l'action ou non.
Un ex :
using System.Threading;
public class ThreadKiller
{
protected bool actif,pause;
public static void Go()
{
try
{
while(actif)
{
if (!pause) System.Console.WriteLine("Plop" );
Thread.Sleep(1000);
}
}
catch(ThreadAbortException e)
{
System.Console.WriteLine("Ouch {0}", e);
}
}
public static void Main()
{
actif=true;
pause=false;
Thread t = new Thread( new ThreadStart(Go) );
t.Start();
actif=false;
}
}
Quand actif=false, le thread se termine tout simplement et on en entend plus parler.
Le thread.abort est viable, mais c'est moins beau. Attention, croire que le thread s'arrète immédiatement apres l'appel à abort() est faux, le système n'arrete le thread qu'un peu plus tard (quand il est en pause je crois), ce qui revient grosso-modo à la solution que j'ai donné, en moins clair.
Sinon, il faut à tout prix éviter l'emploi des primitives stop(), resume() et compagnie... Si on se trompe (ex : on fait 2 resume d'affilé sur le meme thread), on a droit à une belle exception, qu'il faut donc catcher ... et ca fout la merde dans le source pour rien.
Bref, le boolean, ya que ca de vrai
EDIT : pause=false au début, c'est mieux
Marsh Posté le 28-06-2004 à 15:12:28
non, c'est une mauvaise approche. déjà il faudrait utiliser un événement et pas un booléen
Marsh Posté le 28-06-2004 à 16:32:28
du genre ? J'ai beau chercher, je vois pas ce que les évènements viennent faire ici.
Mais bon, je suis ptetre pas dans le coup là, je fais plus ca à longueur de journée
Au passage, cette approche marche trés bien, tout comme la tienne certes, mais présente l'avantage d'etre plus claire. Qui plus est, j'ai déjà vu de nombreux sources de Petzol (ie une brute du win32) procéder de meme.
Ps : pardon pour l'othographe du nom de ce Monsieur dont je ne me rapelle plus
Marsh Posté le 28-06-2004 à 16:51:00
Ha, on me fait signe au bureau d'en face que l'emploi du abort est désastreux
explication : tu ne sais pas ou en est ton thread quand il est aborté, ie, tu ne controle pas le nettoyage éventuel des objets/tableaux/listes dont tu te sert.
Ce qui apporte de l'eau à mon moulin : avec un ptit boolean, tu sais par où passe ton thread.
Sinon, on peut rajouter à mon bout de code des get-set pour faire plus propre, mettre les boolean en private (plus sur).
Marsh Posté le 28-06-2004 à 16:55:22
le abort est pas désastreux en C#, à toi de bien rattraper l'exception. mais ça peut devenir long à gérer. et il faut utiliser des événements avec ton attente, ton thread bien qu'endormi est ininterruptible. utilise les événements. je viens de comprendre. Allo la moule, on parle de synchronisation, de //, pas des event C# !
et les get/set en C#, ça pue.
Marsh Posté le 28-06-2004 à 17:02:27
Taz a écrit : le abort est pas désastreux en C#, à toi de bien rattraper l'exception. mais ça peut devenir long à gérer. et il faut utiliser des événements avec ton attente, ton thread bien qu'endormi est ininterruptible. utilise les événements. je viens de comprendre. Allo la moule, on parle de synchronisation, de //, pas des event C# ! |
putain mais c'est pas vrai, t'es en guerre contre le reste de l'humanité ou quoi ???
tu sais pas repondre correctement, sans te foutre de la gueule des gens ???
si un sujet te fait chier ou ne t'interesse pas, ben tu laisses tomber !
ah et tu peux me preciser aussi en quoi les get/set de C# sont puants ?
Edit : pour info au sujet de la methode Abort(), les gens qui travaillent au framework SDF d'opennetcf.org ont cree une classe adaptateur de la classe Thread. L'appel a la methode Abort() de cette classe renvoit une BestPracticeViolationException (c'est dire l'interet de la methode !!!) . Etant donne que je fais beaucoup plus confiance a ces mecs la (qui je le rappelle travaillent tous sur le framework dotnet chez MS) qu'a toi, je crois que je vais privilegier la methode d'oliv5.
http://www.opennetcf.org/library/O [...] Abort.html
v.
Marsh Posté le 28-06-2004 à 17:51:18
c'est toi qui t'excites. les propriétés, ça te dit quelque chose ? quand à ce que font les autres, c'est leur problème. le Abort ne pose problème qui si on ne le controle pas. T'as quad demander à ces gens de t'expliquer ce qu'est événement, on verra qui est le plus sympa
Marsh Posté le 28-06-2004 à 18:31:46
Taz a écrit : c'est toi qui t'excites. les propriétés, ça te dit quelque chose ? quand à ce que font les autres, c'est leur problème. le Abort ne pose problème qui si on ne le controle pas. T'as quad demander à ces gens de t'expliquer ce qu'est événement, on verra qui est le plus sympa |
je m'excite pas du tout, au contraire je suis en general un animal particulierement placide.
j'ai juste un peu de mal avec ta maniere de repondre a tout le monde.
pour te repondre, oui, je sais ce que sont les proprietes, mais tu n'as pas repondu a ma question ni justifié ta remarque (je cite "les get/set en C#, ça pue" ).
quant a ta derniere trouvaille :
Citation : T'as quad demander à ces gens de t'expliquer ce qu'est événement, on verra qui est le plus sympa |
je ne vais certainement pas deranger les gens en question pour ca. par contre, je suis un eleve particulierement attentif et interesse, j'attends donc de toi que tu m'expliques cela afin que je puisse me rendre compte de la qualite de ton argumentaire.
par contre, je te previens tout de suite des trucs tels que "ca pue" ou "t'as qu'a leur demander" ne me paraissent pas des explications valables, va falloir argumenter un peu plus que ca...
v.
Marsh Posté le 28-06-2004 à 20:54:50
- le C# ne s'est pas doté de propriété pour qu'on écrive des get/set.
- les événements, tu trouveras ça au même chapitre que les mutex, sémaphores, barrière et condition
Marsh Posté le 28-06-2004 à 23:30:05
Taz a écrit : - le C# ne s'est pas doté de propriété pour qu'on écrive des get/set. |
les proprietes sont fait de la meme facon que les get-set, d'ailleurs c'est quasiment équivalent. Je prefere les get-set personnellement, mais c'est kifkif. Pour moi, c'est plus clair c'est tout, car c'est utilisé dans d'autres langages, donc mon code reste uniforme et plus facile a traduire. Je me rapelle avoir passé tout mon jeu de pong en réseau du java vers le C# tres facilement, car, entre autre, il etait bourré de get-set.
Pour ce qui est des evenements, parlons plutot d'event, car c'est le terme anglais qui est utilisé dans les noms des fonctions
Je vois de quoi tu parles, et tu as raison, ca permet bien de faire de la synchro de thread.
Mais en fait, le pb n'est pas là, contrairement a ce que le sujet du topic laiserais supposer, le pb n'est pas de synchroniser 2 threads, mais d'arréter 1 thread
=> D'ou notre petite prise de bec : mon bout de code ne fait pas de synchronisation, il permet juste de controller 1 thread dans sa pause et son arret.
=> D'ou la justesse de ta remarque : les "event" permettent de synchroniser 2 threads, au meme titre que les mutex et les sémaphores.
=> tu as mal lu mon code et la première question de vonm
Marsh Posté le 28-06-2004 à 23:34:00
controller un thread, c'est de la synchronisation. Et je dis événement, je m'en fout du terme anglais. Et ton code je l'ai bien lu, il faut utiliser un événement et pas un booléen, je maintiens
Marsh Posté le 29-06-2004 à 08:49:25
Taz a écrit : controller un thread, c'est de la synchronisation. Et je dis événement, je m'en fout du terme anglais. Et ton code je l'ai bien lu, il faut utiliser un événement et pas un booléen, je maintiens |
ca me surprend un peu car si ma memoire est bonne, en java, l'arret de thread passe par un booleen.
Maintenant, le parallele avec java n'est peut etre pas indique dans ce cas la.
envoie un exemple, peut-etre qu'on comprendra.
Edit: effectivement oliv5, tu as bien saisi de quoi je voulais parler.
v.
Marsh Posté le 29-06-2004 à 09:50:44
Taz a écrit : controller un thread, c'est de la synchronisation. Et je dis événement, je m'en fout du terme anglais. Et ton code je l'ai bien lu, il faut utiliser un événement et pas un booléen, je maintiens |
Ben moi, je maintiens que l'arret définitif d'un thread ne se fait pas par un mutex/semaphore. Ici il n'y a qu'un thread et le boolean actif permet bien de l'arreter.
Note : vnomn veut arréter définitivement son thread, c'est ca sa question si j'ai bien compris.
Sinon, pour mettre en pause un thread, oui, la meilleur solution est le mutex. Encore que ... si ton mutex est actif, et ton thread bloqué, tu peux toujours courir pour que le abort() arrete ton thread => l'arret ne se produit que si ton thread est vivant, d'où l'interet d'une solution simple comme la mienne, pour de petites applis : meme si en pause, le thread est vivant donc l'arret a bien lieu (avec abort() ou avec un boolean)
Mais là n'est pas la question.
La question est : je veux arréter définitivement mon thread.
=> boolean dans le while
Marsh Posté le 29-06-2004 à 11:31:06
bon écoute, tu ferais bien de regarder AutoResetEvent et ManualResetEvent.
un boucle
tant que <test>:
travail
attente
fin thread
doit toujours se traduire par un événement. t'en fais ce que tu veux. bricoles avec tes booléens sinon
Marsh Posté le 29-06-2004 à 13:40:07
Taz a écrit : bon écoute, tu ferais bien de regarder AutoResetEvent et ManualResetEvent. |
Je sens que tu perds ton sang-froid
Merci, mais je sais ce que c'est ces putains de resetEvent!!!
tant que test => c'est exactement ce que j'ai proposé.
travail, rien a redire
attente : sleep
fin thread
Je ne vois pas ou tu fous ton putain de ManualResetEventou ton AutoResetEvent.
Je veux bien un exemple complet car je vois vraiment pas. Je suis sur qu'en ecrivant l'exemple tu verras que ca ne te sert pas, dans notre cas.
Puisque tu as une solution magique, je la veux.
Marsh Posté le 29-06-2004 à 13:55:44
c'est pas comme si ça faisait depuis le début du topic je te disais de lire la documentation. Tu ne sais même pas ce qu'est un événement, alors ne dis pas que c'est nul, ou inapproprié.
Marsh Posté le 29-06-2004 à 14:09:35
Taz a écrit : c'est pas comme si ça faisait depuis le début du topic je te disais de lire la documentation. Tu ne sais même pas ce qu'est un événement, alors ne dis pas que c'est nul, ou inapproprié. |
personne n'a dit que c'etait nul.
inapproprie oui, mais certainement qu'un exemple va nous convaincre...
on est deux a t'en demander un maintenant !
v.
Marsh Posté le 29-06-2004 à 14:11:48
vonm a écrit : |
3
pas pour mettre Taz à l'épreuve, mais par simple curiosité
Marsh Posté le 29-06-2004 à 14:25:48
Taz a écrit : non mais personne sait ce que c'est qu'un événement ? |
mais puisque je te dit que je sais ce que c'est les manuelResetEvent et le AutoResetEvent !!!!
Je ne vois juste absolument pas en quoi ils permettent de resoudre notre problème, qui est, je le rapelle, d'arréter définitivement un thread (et pas le bloquer simplemement !!! l'arréter, fini, nada, plus rien)
Citation : pas pour mettre Taz à l'épreuve, mais par simple curiosité |
Bah moi, si, dsl, mais quand je vois qqu'un d'aussi catégorique et que je suis certain qu'il a tort, soit il a raison et je suis naze, soit il a tord. Personnellement, je m'en fous, j'aimerais bien apprendre un truc aujourd'hui et allait améliorer mes vieilles applis.
Donc j'aimerais bien un exemple, qui resolve le problème du jour (et pas un autre) car je sais comment on se sert des event pour synchroniser 2 threads, mais là n'est pas le problème.
Marsh Posté le 29-06-2004 à 14:30:31
parce que pendant que ton thread dort il est ininterruptible putain, ça saute aux yeux ! dans ce genre de cas, on a souvent des thread qui dorment plusieurs dizaines de secondes, ton booléen, i va être vachement apprécié, il va falloir qu'une itération de complète de la boucle se termine avant de pouvoir finir le thread.
Marsh Posté le 29-06-2004 à 15:04:27
l'exemple de MS est bien
sinon, genre ça
Code :
|
pas testé, ma version de mono segfault, je suis entrain de mettre à jour
Marsh Posté le 29-06-2004 à 15:31:12
Taz a écrit : parce que pendant que ton thread dort il est ininterruptible putain, ça saute aux yeux ! dans ce genre de cas, on a souvent des thread qui dorment plusieurs dizaines de secondes, ton booléen, i va être vachement apprécié, il va falloir qu'une itération de complète de la boucle se termine avant de pouvoir finir le thread. |
Gnnnnnn
Et quand il est bloqué par un event, c'est pareil !!!! Ton abort ne fera rien !! L'OS ne te garantis pas quand le thread est tué !
Donc ca ne change rien !
Marsh Posté le 29-06-2004 à 15:36:13
mais un event n'est pas bloquant si tu lui dit de ne pas l'être ... tu mélanges tout. Si ton thread ne vérifie pas de lui même s'il doit s'arrêter à intervalles réfuliers, il n'y a évidemment pas de solution. par contre, si c'est le cas, il faut utiliser un événement.
Marsh Posté le 29-06-2004 à 15:37:47
Haaa enfin tu nous sort un bout de code.
Je testerais ca, je prefere deja ca au abort() que tu proposait.
(un bout de code vaut mieux qu'un discours pas clair, enervé et enervant du style "mais t'es nul tu vois pas" )
Marsh Posté le 28-06-2004 à 09:33:53
Bonjour,
j'ai une petite question assez classique.
en C#, je dispose d'une classe qui, dans son main, lance un thread qui fait un traitement a intervalle regulier.
static void Main(string[] args)
{
maClasse wss = new maClasse();
// demarre le thread
wss.StartProcess();
}
je ne sais malheureusement pas comment stopper le thread ainsi lancé.
en effet, après quelques essais, je me suis rendu compte que le thread n'etait jamais arrete (ce qui dans l'absolu me semble assez normal).
ma question est donc :
savez-vous comment arreter ce thread de maniere propre ?
v.