EventWaitHandle - Différence entre WaitAny() et WaitOne()
J'ai 3 fils, deux des "travailleurs" et un "manager" . Les "Travailleurs" threads Attend sur EventWaitHandle
que le "gestionnaire" thread sera le signal de l' EventWaitHandle
après que leur augmentation de leurs compteurs.
La seule différence entre les "travailleurs" threads est que l'on utilise EventWaitHandle.WaitAny()
et de l'autre on utilise EventWaitHandle.WaitOne()
.
voici le code:
class Program
{
static void Main(string[] args)
{
MultiThreadedJobs multyThreadedJobs = new MultiThreadedJobs();
multyThreadedJobs.Start();
Console.ReadLine();
multyThreadedJobs.Stop();
}
}
class MultiThreadedJobs : IDisposable
{
private EventWaitHandle syncEvent;
private EventWaitHandle[] syncEventsArray;
private Thread managerThread;
private Thread firstWorkerThread;
private Thread secondWorkerThread;
private volatile bool running = false;
public MultiThreadedJobs() //Ctor
{
syncEvent = new EventWaitHandle(false, EventResetMode.AutoReset, "JobsSyncEvent");
syncEventsArray = new EventWaitHandle[1];
syncEventsArray[0] = syncEvent;
managerThread = new Thread(ManagerThreadMethod);
firstWorkerThread = new Thread(FirstWorkerThreadMethod);
secondWorkerThread = new Thread(SecondWorkerThreadMethod);
}
public void Start()
{
running = true;
managerThread.Start();
firstWorkerThread.Start();
secondWorkerThread.Start();
}
public void Stop()
{
running = false;
}
private void ManagerThreadMethod() //Manager Thread
{
while (running)
{
Thread.Sleep(1000);
syncEvent.Set();
}
}
private void FirstWorkerThreadMethod() //Worker Thread
{
int counter = 0;
while (running)
{
syncEvent.WaitOne();
counter++;
}
}
private void SecondWorkerThreadMethod() //Worker Thread
{
int counter = 0;
while (running)
{
EventWaitHandle.WaitAny(syncEventsArray);
counter++;
}
}
public void Dispose()
{
syncEvent.Close();
}
}
Le problème, c'est juste La deuxième thread de travail avec le EventWaitHandle.WaitAny()
toujours attraper l'Événement, et à mourir de faim le premier thread de travail. au lieu d'environ 50/50 pourcentage de chacun d'eux.
Jetez un oeil à ceci: stackoverflow.com/questions/1816099/...
S'il vous plaît montrer tous les code, où en êtes-vous de faire
merci, mais je ne suis pas d'y voir une réponse pour mon problème
le " Fil.Start()' existe pas dans un autre méthode Start() .
tous les code ici.
S'il vous plaît montrer tous les code, où en êtes-vous de faire
Thread.Start()
?merci, mais je ne suis pas d'y voir une réponse pour mon problème
le " Fil.Start()' existe pas dans un autre méthode Start() .
tous les code ici.
OriginalL'auteur Jacob | 2013-02-06
Vous devez vous connecter pour publier un commentaire.
Vous êtes à la recherche d'une solution à un problème très commun en génie logiciel, le Producteur-consommateur problème. Liés article de Wikipédia a décent des informations de base sur elle, en particulier en montrant comment le faire de manière erronée.
Vous êtes certainement à la poursuite d'une solution, c'est de la mauvaise façon. Un AutoResetEvent est beaucoup trop simpliste. Vous avez déjà trouvé un problème avec elle, elle ne fournit pas équité. De nombreux autres problèmes avec, en particulier, il souffre d'une méchante filetage de la course, lorsque le producteur fil produit aussi des emplois plus rapidement que la consommation de threads.
L'exemple de code est trop artificiel pour offrir une bonne alternative. Faible niveau de verrouillage peut être mis en œuvre par le ReaderWriterLock/Slim classe. Une classe qui est particulièrement bien adaptée pour résoudre producteur/consommateur, les problèmes de .NET 4 BlockingCollection classe. L'appui d'un nombre arbitraire de producteurs et de consommateurs de threads et de fournir une limitation pour s'assurer qu'un programme ne souffle pas en place lorsque les consommateurs ne peuvent pas maintenir en place avec les producteurs. Vous pouvez réécrire votre échantillon à l'aide d'un "faux jeton" que vous passer du producteur au consommateur threads. Un
BlockingColletion<bool>
fait le travail.Processes
pas seulementThreads
, pour ce faire, je suis en utilisantNamed Events
. mais j'ai trouvé que ce mécanisme ne pas donner de l'équité. comme vous l'avez dit. ma question est plus technique. Pourquoi le EventWaitHandle pas donner de l'équité? et est-il un moyen de le forcer à faire il plus juste ?OriginalL'auteur Hans Passant
La WaitHandle classe permet aux clients de faire appel asynchrone et d'attendre:
un seul service Web XML (WaitHandle.WaitOne),
le premier de nombreux services Web XML (WaitHandle.WaitAny), ou
tous de nombreux services Web XML (WaitHandle.WaitAll) pour renvoyer les résultats.
Si vous souhaitez traiter les résultats dès qu'ils arrivent, vous pouvez utiliser le WaitHandle.WaitAny méthode. Cette méthode indique que l'une des opérations a été complété et permettra d'identifier l'opération effectuée.
Les deux méthodes sont overiddable. Et selon les paramètres passés,la mise en œuvre varie.Par exemple,WaitHandle.WaitAny Méthode (WaitHandle[], Int32, Boolean) attend pour l'un quelconque des éléments dans le tableau spécifié pour recevoir un signal, à l'aide d'un entier signé 32 bits pour mesurer l'intervalle de temps, et en précisant si à la sortie de la synchronisation de domaine avant de l'attendre.
WaitHandle.WaitOne Méthode (Int32, Boolean) quand redéfinie dans une classe dérivée, bloque le thread courant
jusqu'à ce que le WaitHandle reçoit un signal, en utilisant 32 bits entier signé à mesurer l'intervalle de temps et en spécifiant
si à la sortie de la synchronisation de domaine avant de l'attendre.
OriginalL'auteur coder