Delen via


Multithreading: Werkdraad maken in MFC

Een worker thread wordt vaak gebruikt om achtergrondtaken af te handelen waarvoor de gebruiker niet hoeft te wachten om de toepassing te blijven gebruiken. Taken zoals herberekening en afdrukken op de achtergrond zijn goede voorbeelden van werkdraden. In dit onderwerp worden de stappen beschreven die nodig zijn om een worker thread te maken. Dit zijn een aantal van de onderwerpen:

Het maken van een werkthread is een relatief eenvoudige taak. Er zijn slechts twee stappen vereist om de thread uit te voeren: de besturingsfunctie implementeren en de thread starten. Het is niet nodig om een klasse af te leiden van CWinThread. U kunt een klasse afleiden als u een speciale versie van CWinThread nodig hebt, maar deze is niet vereist voor de meeste eenvoudige achtergrondthreads. U kunt zonder aanpassingen gebruiken CWinThread .

De thread starten

Er zijn twee overladen versies van AfxBeginThread: een versie die alleen werknemerthreads kan maken en één die zowel UI-threads als werknemerthreads kan maken. Als u wilt beginnen met het uitvoeren van uw werkrolthread met behulp van de eerste overbelasting, roept u AfxBeginThread aan en geeft u de volgende informatie op:

  • Het adres van de besturingsfunctie.

  • De parameter die moet worden doorgegeven aan de besturingsfunctie.

  • (Optioneel) De gewenste prioriteit van de thread. De standaardwaarde is de normale prioriteit. Zie SetThreadPriority in de Windows SDK voor meer informatie over de beschikbare prioriteitsniveaus.

  • (Optioneel) De gewenste stackgrootte voor de thread. De standaardwaarde is dezelfde stackgrootte als de aanmakende thread.

  • (Optioneel) CREATE_SUSPENDED als u wilt dat de thread wordt gemaakt in een onderbroken status. De standaardwaarde is 0 of start de thread normaal.

  • (Optioneel) De gewenste beveiligingskenmerken. De standaardwaarde is dezelfde toegang als de bovenliggende thread. Zie SECURITY_ATTRIBUTES in de Windows SDK voor meer informatie over de indeling van deze beveiligingsgegevens.

AfxBeginThread maakt en initialiseert een CWinThread object voor u, start het en retourneert het adres, zodat u het later kunt raadplegen. Tijdens de procedure worden controles uitgevoerd om ervoor te zorgen dat alle objecten correct worden vrijgegeven als een deel van het creëren mislukt.

De besturingsfunctie implementeren

De besturingsfunctie definieert de thread. Wanneer deze functie wordt aangeroepen, start de thread, en wanneer deze afsluit, stopt de thread. Deze functie moet het volgende prototype hebben:

UINT MyControllingFunction( LPVOID pParam );

De parameter is één waarde. De waarde die de functie in deze parameter ontvangt, is de waarde die is doorgegeven aan de constructor toen het threadobject werd gemaakt. De besturingsfunctie kan deze waarde op elke gewenste manier interpreteren. Het kan worden behandeld als een scalaire waarde of een aanwijzer naar een structuur met meerdere parameters, of kan worden genegeerd. Als de parameter verwijst naar een structuur, kan de structuur niet alleen worden gebruikt om gegevens van de aanroeper door te geven aan de thread, maar ook om gegevens van de thread door te geven aan de aanroeper. Als u een dergelijke structuur gebruikt om gegevens terug te geven aan de beller, moet de thread de beller waarschuwen wanneer de resultaten gereed zijn. Zie Multithreading: Programmeertips voor informatie over de communicatie van de werkthread naar de aanroeper.

Wanneer de functie wordt beëindigd, moet deze een UINT-waarde retourneren die de reden voor beëindiging aangeeft. Deze afsluitcode is doorgaans 0 om succes aan te geven met andere waarden die verschillende typen fouten aangeven. Dit is puur afhankelijk van de implementatie. Sommige threads behouden mogelijk het aantal gebruiksobjecten en retourneren het huidige aantal toepassingen van dat object. Zie Multithreading: Terminating Threads om te zien hoe toepassingen deze waarde kunnen ophalen.

Er gelden enkele beperkingen voor wat u kunt doen in een multithreaded programma dat is geschreven met de MFC-bibliotheek. Zie Multithreading voor beschrijvingen van deze beperkingen en andere tips over het gebruik van threads : Programmeertips.

Voorbeeld van besturingsfunctie

In het volgende voorbeeld ziet u hoe u een besturingsfunctie definieert en gebruikt vanuit een ander gedeelte van het programma.

UINT MyThreadProc( LPVOID pParam )
{
    CMyObject* pObject = (CMyObject*)pParam;

    if (pObject == NULL ||
        !pObject->IsKindOf(RUNTIME_CLASS(CMyObject)))
    return 1;   // if pObject is not valid

    // do something with 'pObject'

    return 0;   // thread completed successfully
}

// inside a different function in the program
.
.
.
pNewObject = new CMyObject;
AfxBeginThread(MyThreadProc, pNewObject);
.
.
.

Waar wil je meer over weten?

Zie ook

Multithreading met C++ en MFC