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 je 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 řídící 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 pro vlákna uživatelského rozhraní a jedna pro pracovní vlákna. Chcete-li zahájit provádění vašeho pracovního vlákna, zavolejte AfxBeginThread s poskytnutím následujících informací:

  • Adresa řídící funkce.

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

  • (nepovinné) 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.

  • (nepovinný) 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.

  • (nepovinný) 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.

  • (nepovinný) Požadované atributy zabezpečení. Výchozí hodnota je stejný přístup jako nadřazené vlákno. Další informace o formátu informací zabezpečení 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ě zrušeny, takže by neměla selhat žádná část tvorby.

Implementace řídící funkce

Řídící 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. Řídící funkce může interpretovat tuto hodnotu jakýmkoli způsobem si vybere. Může být považována za skalární hodnotu nebo ukazatel na strukturu, obsahující více parametrů 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 zpět z vlákna 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 kdy jsou výsledky připraveny. Pro informace o komunikaci z pracovního vlákna k volajícímu si prohlédněte 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 nebo jiné hodnoty, označující různé typy 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, prohlédněte si Multithreading: Ukončení vláken.

Existují některá omezení na to, co můžete dělat ve vícevláknovém programu, vytvořeném pomocí knihovny MFC. Pro popisy těchto omezení a jiné tipy pro používání vláken si prohlédněte Multithreading: Programovací tipy.

Příklad řídící funkce

Následující příklad ukazuje, jak definovat řídící 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);
.
.
.

Co chcete vědět více?

Viz také

Koncepty

Multithreading s C++ a knihovnou MFC