Udostępnij za pośrednictwem


Wskazówki: adaptacja istniejącego kodu do potrzeb zadań lekkich

W tym temacie opisano, w jaki sposób dostosować istniejący kod, który używa interfejsu API systemu Windows do tworzenia i wykonywania wątku używania lekki zadanie.

A lekki zadania jest zadaniem, które można zaplanować bezpośrednio z concurrency::Scheduler lub concurrency::ScheduleGroup obiektu.Lekki zadań są przydatne, gdy dostosowanie istniejącego kodu, aby korzystać z funkcji planowania środowiska wykonawczego współbieżności.

Wymagania wstępne

Przed rozpoczęciem tego instruktażu, przeczytaj temat Harmonogram zadań (współbieżność środowiska wykonawczego).

Przykład

Opis

Poniższy przykład ilustruje typowe sposoby wykorzystania programu Windows API do tworzenia i wykonywania wątku.W poniższym przykładzie użyto funkcji CreateThread: funkcji do wywołania MyThreadFunction w oddzielnym wątku.

Kod

// windows-threads.cpp
#include <windows.h>
#include <tchar.h>
#include <strsafe.h>

#define BUF_SIZE 255

DWORD WINAPI MyThreadFunction(LPVOID param);

// Data structure for threads to use. 
typedef struct MyData {
    int val1;
    int val2;
} MYDATA, *PMYDATA;

int _tmain()
{
   // Allocate memory for thread data.
   PMYDATA pData = (PMYDATA) HeapAlloc(GetProcessHeap(), 
      HEAP_ZERO_MEMORY, sizeof(MYDATA));

   if( pData == NULL )
   {
      ExitProcess(2);
   }

   // Set the values of the thread data.
   pData->val1 = 50;
   pData->val2 = 100;

   // Create the thread to begin execution on its own.
   DWORD dwThreadId;
   HANDLE hThread = CreateThread( 
      NULL,                   // default security attributes
      0,                      // use default stack size  
      MyThreadFunction,       // thread function name
      pData,                  // argument to thread function 
      0,                      // use default creation flags 
      &dwThreadId);           // returns the thread identifier  

   if (hThread == NULL) 
   {      
      ExitProcess(3);
   }

   // Wait for the thread to finish.
   WaitForSingleObject(hThread, INFINITE);

   // Close the thread handle and free memory allocation.
   CloseHandle(hThread);
   HeapFree(GetProcessHeap(), 0, pData);

   return 0;
}

DWORD WINAPI MyThreadFunction(LPVOID lpParam)
{
   PMYDATA pData = (PMYDATA)lpParam;

   // Use thread-safe functions to print the parameter values.

   TCHAR msgBuf[BUF_SIZE];
   StringCchPrintf(msgBuf, BUF_SIZE, TEXT("Parameters = %d, %d\n"), 
     pData->val1, pData->val2); 

   size_t cchStringSize;
   StringCchLength(msgBuf, BUF_SIZE, &cchStringSize);

   DWORD dwChars;
   WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), msgBuf, (DWORD)cchStringSize, &dwChars, NULL);

   return 0;
}

Komentarze

Ten przykład generuje następujące wyniki.

  

Poniższe kroki pokazują, w jaki sposób dostosować w przykładzie kodu do wykonania tego samego zadania za pomocą środowiska wykonawczego współbieżności.

Aby dostosować przykład użycia lekkiego zadania

  1. Dodaj #include w dyrektywie dla concrt.h pliku nagłówka.

    #include <concrt.h>
    
  2. Dodaj using w dyrektywie dla concurrency obszaru nazw.

    using namespace concurrency;
    
  3. Zmiana deklaracji MyThreadFunction używać __cdecl konwencji wywoływania i przywrócić void.

    void __cdecl MyThreadFunction(LPVOID param);
    
  4. Modyfikowanie MyData strukturę, aby uwzględnić concurrency::event obiekt, który sygnalizuje do aplikacji głównej zakończone zadanie.

    typedef struct MyData {
        int val1;
        int val2;
        event signal;
    } MYDATA, *PMYDATA;
    
  5. Zastąpić wywołanie CreateThread z wezwaniem do concurrency::CurrentScheduler::ScheduleTask metody.

    CurrentScheduler::ScheduleTask(MyThreadFunction, pData);
    
  6. Zastąpić wywołanie WaitForSingleObject z wezwaniem do concurrency::event::wait metoda czekać na zakończenie zadania.

    // Wait for the task to finish.
    pData->signal.wait();
    
  7. Usunąć wywołanie CloseHandle.

  8. Zmienianie podpisu definicja MyThreadFunction aby dopasować krok 3.

    void __cdecl MyThreadFunction(LPVOID lpParam)
    
  9. Na koniec MyThreadFunction funkcji, call concurrency::event::set metoda na sygnał do aplikacji głównej zakończone zadanie.

    pData->signal.set();
    
  10. Usuń return instrukcji od MyThreadFunction.

Przykład

Opis

Wypełniony przykładzie pokazano kod, który używa lekki zadania do wywołania MyThreadFunction funkcji.

Kod

// migration-lwt.cpp 
// compile with: /EHsc
#include <windows.h>
#include <tchar.h>
#include <strsafe.h>
#include <concrt.h>

using namespace concurrency;

#define BUF_SIZE 255

void __cdecl MyThreadFunction(LPVOID param);

// Data structure for threads to use. 
typedef struct MyData {
    int val1;
    int val2;
    event signal;
} MYDATA, *PMYDATA;

int _tmain()
{
   // Allocate memory for thread data.
   PMYDATA pData = (PMYDATA) HeapAlloc(GetProcessHeap(), 
      HEAP_ZERO_MEMORY, sizeof(MYDATA));

   if( pData == NULL )
   {
      ExitProcess(2);
   }

   // Set the values of the thread data.
   pData->val1 = 50;
   pData->val2 = 100;

   // Create the thread to begin execution on its own.
   CurrentScheduler::ScheduleTask(MyThreadFunction, pData);

   // Wait for the task to finish.
   pData->signal.wait();

   // Free memory allocation.
   HeapFree(GetProcessHeap(), 0, pData);

   return 0;
}

void __cdecl MyThreadFunction(LPVOID lpParam)
{
   PMYDATA pData = (PMYDATA)lpParam;

   // Use thread-safe functions to print the parameter values.

   TCHAR msgBuf[BUF_SIZE];
   StringCchPrintf(msgBuf, BUF_SIZE, TEXT("Parameters = %d, %d\n"), 
     pData->val1, pData->val2); 

   size_t cchStringSize;
   StringCchLength(msgBuf, BUF_SIZE, &cchStringSize);

   DWORD dwChars;
   WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), msgBuf, (DWORD)cchStringSize, &dwChars, NULL);

   pData->signal.set();
}

Zobacz też

Informacje

Klasa harmonogramu

Koncepcje

Harmonogram zadań (współbieżność środowiska wykonawczego)