Sdílet prostřednictvím


Multithreading: Vytváření pracovních vláken

Pracovní vlákno se běžně používá ke zpracování úkolů na pozadí, na které by neměl muset uživatel čekat pro pokračování v používání aplikace.Úlohy jako přepočet a tisk na pozadí jsou dobrým příkladem pracovních vláken.Toto téma podrobně popisuje kroky, potřebné k vytvoření pracovního vlákna.Témata zahrnují:

  • Spuštění vlákna

  • Implementace řídicí funkce

  • Příklad

Vytvoření pracovního vlákna je poměrně jednoduchá úloha.Pouze dva kroky jsou požadovány pro spuštění vašeho vlákna: implementace řídící funkce a spuštění vlákna.Není nutné odvozovat třídu z CWinThread.Můžete třídu odvodit, pokud potřebujete speciální verzi CWinThread, ale není to vyžadováno pro většinu jednoduchých pracovních vláken.Můžete použít CWinThread beze změny.

Spuštění vlákna

Existují dvě přetížené verze AfxBeginThread: jedna, která může vytvořit pouze pracovní podprocesy a jedna, která může vytvářet vlákna uživatelského rozhraní a pracovních podprocesů.Chcete-li zahájit provádění vašeho pracovního vlákna pomocí prvního přetížení, zavolejte funkci AfxBeginThread s poskytnutím následujících informací:

  • Adresa řídící funkce.

  • Parametr, který má být předán řídicí funkci.

  • (Volitelné) Požadovaná priorita vlákna.Výchozí hodnota je normální priorita.Další informace o možných úrovních priority naleznete v tématu SetThreadPriority v Windows SDK.

  • (Volitelné) Požadovaná velikost zásobníku pro vlákno.Výchozí hodnota je stejná velikost zásobníku jako u vytvářeného vlákna.

  • (Volitelné) CREATE_SUSPENDED, pokud chcete, aby bylo vlákno vytvořeno v pozastaveném stavu.Výchozí hodnota je 0 nebo normální spuštění vlákna.

  • (Volitelné) Požadované atributy zabezpečení.Výchozí hodnota je stejný přístup jako k nadřazenému vláknu.Další informace o formátu bezpečnostních informací naleznete v tématu SECURITY_ATTRIBUTES v Windows SDK.

AfxBeginThread vytvoří a inicializuje objekt CWinThread, spustí jej a vrátí jeho adresu, takže je možné se na něj později odkazovat.Kontroly jsou prováděny v celém procesu, aby bylo zajištěno, že všechny objekty jsou správně uvolněny v případě, že selže některá část vytvoření.

Implementace řídicí funkce

Řídicí funkce definuje vlákno.Po zadání této funkce se vlákno spustí a při jejím ukončení se vlákno ukončí.Tato funkce by měla mít následující prototyp:

UINT MyControllingFunction( LPVOID pParam );

Parametr je jednoduchá hodnota.Hodnota, kterou funkce přijímá v tomto parametru, je hodnota, která byla předána konstruktoru při vytvoření objektu vlákna.Řídicí funkce může interpretovat tuto hodnotu, jakýmkoli způsobem si vybere.Může být považována za skalární hodnotu nebo ukazatele na strukturu s více parametry nebo může být ignorována.Pokud parametr odkazuje na strukturu, struktura může být použita nejen pro předání dat od volajícího vláknu, ale také k předání dat z vlákna zpět volajícímu.Použijete-li takovouto strukturu k předání dat zpět volajícímu, musí vlákno oznámit volajícímu, že jsou výsledky připraveny.Informace o komunikaci z pracovního vlákna k volajícímu naleznete v tématu Multithreading: programovací tipy.

Když funkce skončí, měla by vrátit hodnotu UINT označující důvod ukončení.Obvykle je tento kód ukončení 0 pro označení úspěchu a jiná hodnota pro označení různých typů chyb.Toto závisí čistě na implementaci.Některá vlákna mohou udržovat počty využití objektů a vracet aktuální počet využití daného objektu.Abyste zjistili, jak mohou aplikace načíst tuto hodnotu, viz Multithreading: ukončení vláken.

Existují určitá omezení na to, co můžete dělat ve vícevláknovém programu, vytvořeném pomocí knihovny MFC.Popisy těchto omezení a další tipy pro používání vláken naleznete v tématu Multithreading: programovací tipy.

Příklad řídicí funkce

Následující příklad ukazuje, jak definovat řídicí funkci a použít ji z jiné části programu.

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

O čem chcete vědět více?

Viz také

Koncepty

Multithreading s použitím jazyka C++ a prostředí MFC