Megosztás a következőn keresztül:


Többszálú programozás: Munkaszálak létrehozása az MFC-ben

A munkavégzőszálakat gyakran használják olyan háttérfeladatok kezelésére, amelyeket a felhasználónak nem kell megvárnia az alkalmazás használatának folytatására. Az olyan feladatok, mint az újraszámítás és a háttérnyomtatás, jó példák a munkaszálakra. Ez a témakör a munkaszál létrehozásához szükséges lépéseket bemutatja. A témakörök a következők:

A munkamenet létrehozása viszonylag egyszerű feladat. Csak két lépésre van szükség a szál futtatásához: a vezérlő függvény implementálásához és a szál elindításához. Nem szükséges osztályt levezetni a CWinThreadból. Osztályt hozhat létre, ha speciális verzióra van szüksége CWinThread, de a legtöbb egyszerű munkaszálhoz erre nincs szükség. Módosítás nélkül is használható CWinThread .

A szál indítása

A AfxBeginThread két túlterhelt verziója létezik: az egyik csak munkaszálakat tud létrehozni, a másik pedig felhasználói felületi szálakat és munkaszálakat is. A feldolgozószál első túlterheléssel történő végrehajtásának megkezdéséhez hívja meg az AfxBeginThread parancsot, és adja meg a következő információkat:

  • A vezérlő függvény címe.

  • A vezérlő függvénynek átadni kívánt paraméter.

  • (Nem kötelező) A szál kívánt prioritása. Az alapértelmezett érték a normál prioritás. Az elérhető prioritási szintekről további információt a Windows SDK SetThreadPriority szolgáltatásában talál.

  • (Nem kötelező) A szál kívánt veremmérete. Az alapértelmezett érték ugyanaz a méretverem, mint a létrehozási szál.

  • (Nem kötelező) CREATE_SUSPENDED, ha azt szeretné, hogy a szál felfüggesztett állapotban legyen létrehozva. Az alapértelmezett érték 0, vagy a szálat normál módon indítja el.

  • (Nem kötelező) A kívánt biztonsági attribútumok. Az alapértelmezett hozzáférés megegyezik a szülőszáléval. A biztonsági információk formátumáról további információt a Windows SDK SECURITY_ATTRIBUTES című témakörben talál.

AfxBeginThread létrehoz és inicializál egy CWinThread objektumot, elindítja és visszaadja a címét, hogy később hivatkozhass rá. Az eljárás során ellenőrzik, hogy az összes objektum megfelelően van-e felszabadítva, ha a létrehozás bármely része sikertelen.

A vezérlő függvény implementálása

A vezérlő függvény határozza meg a szálat. A függvény beírása után a szál elindul, és kilépéskor a szál leáll. Ennek a függvénynek a következő prototípust kell tartalmaznia:

UINT MyControllingFunction( LPVOID pParam );

A paraméter egyetlen érték. A függvény ebben a paraméterben kapott értéke az az érték, amelyet a konstruktornak a szálobjektum létrehozásakor ad át. A vezérlő függvény bármilyen módon értelmezheti ezt az értéket. Skaláris értékként vagy több paramétert tartalmazó struktúra mutatójaként is kezelhető, vagy figyelmen kívül hagyható. Ha a paraméter egy struktúrára hivatkozik, a struktúra nemcsak arra használható, hogy adatokat adjon át a hívótól a szálnak, hanem adatokat is továbbíthat a szálról a hívónak. Ha egy ilyen struktúrával továbbítja az adatokat a hívónak, a szálnak értesítenie kell a hívót, ha az eredmények készen állnak. A feldolgozó szálról a hívó felé irányuló kommunikációról további információt a Többszálas: Programozási tippek című témakörben talál.

Ha a függvény leáll, egy UINT értéket kell visszaadnia, amely jelzi a megszakítás okát. Ez a kilépési kód általában 0, ami a siker jelzése, míg más értékek különböző típusú hibákra utalnak. Ez kizárólag a megvalósítástól függ. Egyes szálak fenntarthatják az objektumok használati számát, és visszaadhatják az objektum aktuális felhasználási számát. Ha meg szeretné tudni, hogy az alkalmazások hogyan tudják lekérni ezt az értéket, olvassa el a Többszálas: Szálak megszakítása című témakört.

Az MFC-kódtárral írt többszálú programokban bizonyos korlátozások vonatkoznak a műveletekre. A korlátozások leírását és a szálak használatával kapcsolatos egyéb tippeket a Többszálas: Programozási tippek című témakörben találhatja meg.

Vezérlőfüggvény példa

Az alábbi példa bemutatja, hogyan definiálhat egy vezérlőfüggvényt, és hogyan használhatja azt a program egy másik részéből.

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);
.
.
.

Miről szeretne többet tudni?

Lásd még

Többszálúság C++ és MFC használatával