チュートリアル: 既存のコードを改変して軽量タスクを使用する
ここでは、Windows API を使用する既存のコードを改変して、軽量タスクを使用するスレッドを作成および実行する方法について説明します。
A 軽量タスク から直接スケジュールするタスクには、 concurrency::Scheduler または concurrency::ScheduleGroup オブジェクト。軽量タスクは、既存のコードを改変して同時実行ランタイムのスケジュール機能を使用する場合に有用です。
必須コンポーネント
このチュートリアルを開始する前に、「タスク スケジューラ (同時実行ランタイム)」を読んでください。
例
Description
Windows API を使用してスレッドを作成および実行する一般的な方法を次の例に示します。この例では、CreateThread 関数を使用して、MyThreadFunction を別個のスレッドで呼び出しています。
コード
// 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;
}
コメント
この例を実行すると、次の出力が生成されます。
Parameters = 50, 100
同時実行ランタイムを使用して同じタスクを実行するようにこのコード例を改変する手順を次に示します。
軽量タスクを使用するように例を改変するには
ヘッダー ファイル concrt.h の #include ディレクティブを追加します。
#include <concrt.h>
concurrency 名前空間の using ディレクティブを追加します。
using namespace concurrency;
MyThreadFunction の宣言を次のように変更して、__cdecl 呼び出し規約を使用すると共に、void を返します。
void __cdecl MyThreadFunction(LPVOID param);
変更、 MyDataを含めるには、構造体は、 concurrency::event 、メインのアプリケーションに、タスクが完了したことを通知するオブジェクト。
typedef struct MyData { int val1; int val2; event signal; } MYDATA, *PMYDATA;
呼び出しを置き換えますCreateThreadへの呼び出しで、 concurrency::CurrentScheduler::ScheduleTask メソッド。
CurrentScheduler::ScheduleTask(MyThreadFunction, pData);
呼び出しを置き換えますWaitForSingleObjectへの呼び出しで、 concurrency::event::wait メソッドは、タスクが完了するまで待機します。
// Wait for the task to finish. pData->signal.wait();
CloseHandle 呼び出しを削除します。
手順 3. に合わせて、MyThreadFunction の定義のシグネチャを変更します。
void __cdecl MyThreadFunction(LPVOID lpParam)
最後に、 MyThreadFunction 、関数を呼び出す、 concurrency::event::set メソッドは、メインのアプリケーションに、タスクが完了したことを通知します。
pData->signal.set();
return ステートメントを MyThreadFunction から削除します。
例
Description
次の完成版の例に、軽量タスクを使用して MyThreadFunction 関数を呼び出すためのコードを示します。
コード
// 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();
}