Ik heb een aangepaste ThreadPool
gemaakt die een aantal win32-threads start met _beginthreadex()
. De threads draaien op een eenvoudige lus die probeert taken uit een blokkeerwachtrij te verwijderen, maar soms moet ik de threads stoppen en als ze zijn geblokkeerd op Dequeue
weet ik niet hoe ik de code moet ophalen threads uit die blokkeringstoestand.
void ThreadPool::Loop()
{
while(_running)
{
try
{
//Attempts to dequeue a task and run it
_taskQueue.Dequeue()->Run();
}
catch(BlockingQueueTerminate&)
{
//Eat the exception and check the running flag
continue;
}
}
}
Mijn idee was om hetzelfde aantal speciale taken in te voeren (laten we ze "beëindigingstaken" noemen) omdat er threads in de pool zijn en elke "beëindigingstaak" _endthreadex (0)
zal aanroepen om te sluiten de draad. Als er andere taken in de blokkeerwachtrij staan, zal het me niet echt schelen, want zodra ik een taak uitschakel, voer ik deze uit en controleer ik de vlag _running
om te bepalen of de thread nodig heeft om nog meer taken op te schorten.
void TerminationTask::Run()
{
_endthreadex(0);
}
Ik heb verschillende zorgen over deze aanpak; voornamelijk, als ik een niet-beëindigende taak heb verwerkt en de vlag _running
is ingesteld op false
, zal mijn thread _endthreadex (0)
niet aanroepen wanneer het de lus verlaat. Ik vroeg me af of ik aan het einde van de lus _endthreadex (0)
kon bellen als volgt:
void ThreadPool::Loop()
{
while(_running)
{
try
{
//Attempts to dequeue a task and run it
_taskQueue.Dequeue()->Run();
}
catch(BlockingQueueTerminate&)
{
//Eat the exception and check the running flag
continue;
}
}
_endthreadex(0);
}
Zal dit een conflict veroorzaken met mijn TerminationTask
of zal de thread de lus direct verlaten na het uitvoeren van TerminationTask :: Run()
(dwz het zal _endthreadex (niet aanroepen) 0)
twee keer)? Verder is er een betere aanpak dan dit?