Procédure pas à pas : adaptation d’un code existant pour l’utilisation de tâches légères
Cette rubrique montre comment adapter le code existant qui utilise l’API Windows pour créer et exécuter un thread pour utiliser une tâche légère.
Une tâche légère est une tâche que vous planifiez directement à partir d’un objet concurrency ::Scheduler ou concurrency ::ScheduleGroup. Les tâches légères s’avèrent utiles quand vous adaptez du code existant pour utiliser les fonctionnalités de planification du runtime d’accès concurrentiel.
Prérequis
Avant de commencer cette procédure pas à pas, lisez la rubrique Planificateur de tâches.
Exemple
L’exemple suivant illustre l’utilisation classique de l’API Windows pour créer et exécuter un thread. Cet exemple utilise la fonction CreateThread pour appeler le MyThreadFunction
thread distinct.
Code initial
// 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;
}
Cet exemple produit la sortie suivante.
Parameters = 50, 100
Les étapes suivantes montrent comment adapter l’exemple de code pour utiliser le runtime d’accès concurrentiel pour effectuer la même tâche.
Pour adapter l’exemple pour utiliser une tâche légère
- Ajoutez une
#include
directive pour le fichier d’en-tête concrt.h.
#include <concrt.h>
- Ajoutez une
using
directive pour l’espaceconcurrency
de noms.
using namespace concurrency;
- Modifiez la déclaration de l’utilisation de
MyThreadFunction
la convention d’appel__cdecl
et retournezvoid
.
void __cdecl MyThreadFunction(LPVOID param);
- Modifiez la
MyData
structure pour inclure un objet concurrency ::event qui signale à l’application principale que la tâche a terminée.
typedef struct MyData {
int val1;
int val2;
event signal;
} MYDATA, *PMYDATA;
- Remplacez l’appel par
CreateThread
un appel à la méthode concurrency ::CurrentScheduler ::ScheduleTask .
CurrentScheduler::ScheduleTask(MyThreadFunction, pData);
- Remplacez l’appel par
WaitForSingleObject
un appel à la méthode concurrency ::event ::wait pour attendre la fin de la tâche.
// Wait for the task to finish.
pData->signal.wait();
Supprimez l’appel à
CloseHandle
.Modifiez la signature de la définition de
MyThreadFunction
l’étape 3.
void __cdecl MyThreadFunction(LPVOID lpParam)
- À la fin de la
MyThreadFunction
fonction, appelez la méthode concurrency ::event ::set pour signaler à l’application principale que la tâche a terminée.
pData->signal.set();
- Supprimez l’instruction
return
deMyThreadFunction
.
Code terminé
L’exemple terminé suivant montre le code qui utilise une tâche légère pour appeler la MyThreadFunction
fonction.
// 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();
}