Share via


Multithreading: Vytváření pracovních vláken v prostředí MFC

Pracovní vlákno se běžně používá ke zpracování úloh na pozadí, na které by uživatel neměl čekat, než bude pokračovat v používání aplikace. Dobrými příklady pracovních vláken jsou úlohy, jako je přepočet a tisk na pozadí. Toto téma podrobně popisuje kroky potřebné k vytvoření pracovního vlákna. Témata:

Vytvoření pracovního vlákna je relativně jednoduchá úloha. Spuštění vlákna vyžaduje pouze dva kroky: implementaci řídicí funkce a spuštění vlákna. Není nutné odvodit třídu z CWinThread. Třídu lze odvodit, pokud potřebujete speciální verzi CWinThread, ale není vyžadována pro většinu jednoduchých pracovních vláken. Můžete použít CWinThread bez úprav.

Spuštění vlákna

Existují dvě přetížené verze AfxBeginThread: jedna, která může vytvářet pouze pracovní vlákna, a jedna, která může vytvořit vlákna uživatelského rozhraní i pracovní vlákna. Chcete-li zahájit provádění pracovního vlákna pomocí prvního přetížení, zavolejte AfxBeginThread a zadejte následující informace:

  • Adresa řídicí funkce.

  • Parametr, který se má předat řídicí funkci.

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

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

  • (Volitelné) CREATE_SUSPENDED, pokud chcete, aby se vlákno vytvořilo v pozastaveném stavu. Výchozí hodnota je 0 nebo normálně spusťte vlákno.

  • (Volitelné) Požadované atributy zabezpečení. Výchozí hodnota je stejný přístup jako nadřazené vlákno. Další informace o formátu těchto informací o zabezpečení najdete v tématu SECURITY_ATTRIBUTES v sadě Windows SDK.

AfxBeginThread vytvoří a inicializuje CWinThread objekt za vás, spustí ho a vrátí jeho adresu, abyste na něj později mohli odkazovat. Kontroly jsou provedeny v průběhu postupu, aby se zajistilo, že všechny objekty jsou správně uvolněny, pokud všechny části vytváření selžou.

Implementace řídicí funkce

Řídicí funkce definuje vlákno. Po zadání této funkce se vlákno spustí a když se ukončí, vlákno se ukončí. Tato funkce by měla mít následující prototyp:

UINT MyControllingFunction( LPVOID pParam );

Parametr je jedna hodnota. Hodnota, kterou funkce přijme v tomto parametru, je hodnota, která byla předána konstruktoru při vytvoření objektu vlákna. Řídicí funkce může tuto hodnotu interpretovat jakýmkoli způsobem, který zvolí. Lze ji považovat za skalární hodnotu nebo ukazatel na strukturu obsahující více parametrů nebo ji lze ignorovat. Pokud parametr odkazuje na strukturu, lze strukturu použít nejen k předávání dat z volajícího do vlákna, ale také k předávání dat zpět z vlákna volajícímu. Pokud takovou strukturu použijete k předání dat zpět volajícímu, vlákno musí volajícímu oznámit, až budou výsledky připravené. Informace o komunikaci z pracovního vlákna volajícímu naleznete v tématu Multithreading: Programování Tipy.

Když se funkce ukončí, měla by vrátit hodnotu UINT označující důvod ukončení. Obvykle je tento ukončovací kód 0 označující úspěch jinými hodnotami označujícími různé typy chyb. To je čistě závislé na implementaci. Některá vlákna můžou udržovat počty využití objektů a vrátit aktuální počet použití tohoto objektu. Pokud chcete zjistit, jak můžou aplikace načíst tuto hodnotu, přečtěte si téma Multithreading: Ukončování vláken.

Existují určitá omezení toho, co můžete dělat v multithreaded programu napsaného pomocí knihovny MFC. Popis těchto omezení a dalších tipů k používání vláken naleznete v tématu Multithreading: Programování 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íc?

Viz také

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