Wskazówki: adaptacja istniejącego kodu do potrzeb zadań lekkich
W tym temacie pokazano, jak dostosować istniejący kod, który używa interfejsu API systemu Windows do tworzenia i wykonywania wątku w celu użycia uproszczonego zadania.
Uproszczone zadanie to zadanie zaplanowane bezpośrednio z poziomu współbieżności::Scheduler lub współbieżności::ScheduleGroup obiektu. Uproszczone zadania są przydatne podczas dostosowywania istniejącego kodu do korzystania z funkcji planowania środowiska uruchomieniowego współbieżności.
Wymagania wstępne
Przed rozpoczęciem tego przewodnika przeczytaj temat Harmonogram zadań.
Przykład
Poniższy przykład ilustruje typowe użycie interfejsu API systemu Windows do tworzenia i wykonywania wątku. W tym przykładzie użyto funkcji CreateThread do wywołania MyThreadFunction
elementu w osobnym wątku.
Kod początkowy
// 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;
}
W tym przykładzie są generowane następujące dane wyjściowe.
Parameters = 50, 100
W poniższych krokach pokazano, jak dostosować przykład kodu, aby użyć środowiska uruchomieniowego współbieżności w celu wykonania tego samego zadania.
Aby dostosować przykład użycia lekkiego zadania
- Dodaj dyrektywę
#include
dla pliku nagłówka concrt.h.
#include <concrt.h>
- Dodaj dyrektywę
using
dlaconcurrency
przestrzeni nazw.
using namespace concurrency;
- Zmień deklarację ,
MyThreadFunction
aby użyć__cdecl
konwencji wywoływania i zwrócić wartośćvoid
.
void __cdecl MyThreadFunction(LPVOID param);
- Zmodyfikuj strukturę tak
MyData
, aby zawierała obiekt concurrency::event , który sygnalizuje główną aplikację, którą zadanie zostało zakończone.
typedef struct MyData {
int val1;
int val2;
event signal;
} MYDATA, *PMYDATA;
- Zastąp wywołanie
CreateThread
metody wywołaniem współbieżności::CurrentScheduler::ScheduleTask.
CurrentScheduler::ScheduleTask(MyThreadFunction, pData);
- Zastąp wywołanie metody wywołaniem
WaitForSingleObject
współbieżności::event::wait, aby poczekać na zakończenie zadania.
// Wait for the task to finish.
pData->signal.wait();
Usuń wywołanie metody .
CloseHandle
Zmień sygnaturę definicji,
MyThreadFunction
aby dopasować krok 3.
void __cdecl MyThreadFunction(LPVOID lpParam)
- Na końcu
MyThreadFunction
funkcji wywołaj metodę concurrency::event::set , aby zasygnalizować główną aplikację, którą zadanie zostało zakończone.
pData->signal.set();
- Usuń instrukcję
return
zMyThreadFunction
.
Ukończony kod
Poniższy ukończony przykład przedstawia kod, który używa uproszczonego zadania do wywoływania MyThreadFunction
funkcji.
// 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ż
Opinia
https://aka.ms/ContentUserFeedback.
Dostępne już wkrótce: W 2024 r. będziemy stopniowo wycofywać zgłoszenia z serwisu GitHub jako mechanizm przesyłania opinii na temat zawartości i zastępować go nowym systemem opinii. Aby uzyskać więcej informacji, sprawdź:Prześlij i wyświetl opinię dla