Cプログラムで使うWindowsスレッドAPI入門:CreateThread()と待機関数の基本
Windows APIでは、スレッドはCreateThread()関数を使って生成します。Pthreadsの場合と同様に、セキュリティ情報、スタックサイズ、スレッド作成フラグといった一連の属性がこの関数へ渡されます。以下のサンプルプログラムでは、これらの属性にデフォルト値を使用しています。デフォルト設定では、スレッドは最初からサスペンド(中断)状態になるのではなく、CPUスケジューラによってすぐに実行可能な状態になります。
合計値を計算するスレッドを生成した後、親スレッドはその完了を待ってからSumの値を出力しなければなりません。Sumの値は合計計算スレッド側で設定されるためです。Pthreadsのプログラムでは、pthread_join()文を使って親スレッドが合計計算スレッドの終了を待機していました。Windows APIでは、同じ役割をWaitForSingleObject()関数が担います。この関数を呼び出すと、生成元のスレッドは合計計算スレッドが終了するまでブロックされます。
複数スレッドを待機するWaitForMultipleObjects()
複数のスレッドすべての完了を待ちたい場合には、WaitForMultipleObjects()関数を使用します。この関数には、次の4つのパラメータを渡します。
- 待機対象となるオブジェクトの数
- オブジェクト配列へのポインタ
- すべてのオブジェクトがシグナル状態になったかどうかを示すフラグ
- タイムアウト時間(またはINFINITE)
たとえば、THandlesがサイズNのスレッドHANDLEオブジェクトの配列である場合、親スレッドは次の1文ですべての子スレッドの完了を待機できます。
WaitForMultipleObjects(N, THandles, TRUE, INFINITE);
Windows APIを使ったマルチスレッドCプログラムの例
以下は、Windows APIを利用して別スレッドで0から指定された整数までの総和を計算する完全なサンプルコードです。引数として整数を1つ受け取り、その値までの合計を子スレッドが算出し、親スレッドが結果を出力します。
#include<windows.h>
#include<stdio.h>
DWORD Sum;
/* data is shared by the thread(s) */
/* thread runs in this separate function */
DWORD WINAPI Summation(LPVOID Param){
DWORD Upper = *(DWORD*)Param;
for (DWORD i = 0; i <= Upper; i++)
Sum += i;
return 0;
}
int main(int argc, char *argv[]){
DWORD ThreadId;
HANDLE ThreadHandle;
int Param;
if (argc != 2){
fprintf(stderr,"An integer parameter is required\n");
return -1;
}
Param = atoi(argv[1]);
if (Param < 0){
fprintf(stderr,"An integer >= 0 is required\n");
return -1;
}
/* create the thread */
ThreadHandle = CreateThread( NULL, /* default security attributes */ 0, /* default stack size */
Summation, /* thread function */ &Param, /* parameter to thread function */ 0, /* default creation flags */ &ThreadId);
/* returns the thread identifier */
if (ThreadHandle != NULL){
/* now wait for the thread to finish */ WaitForSingleObject(ThreadHandle,INFINITE);
/* close the thread handle */
CloseHandle(ThreadHandle);
printf("sum = %d\n",Sum);
}
}コードのポイント
- CreateThread():第1引数にNULL(デフォルトのセキュリティ属性)、第2引数に0(デフォルトのスタックサイズ)を指定し、スレッド関数として
Summation、その引数として&Paramを渡しています。 - WaitForSingleObject():タイムアウトに
INFINITEを指定することで、子スレッドが終了するまで無期限に待機します。 - CloseHandle():使用済みのスレッドハンドルを明示的にクローズし、リソースリークを防ぎます。
このように、Windows APIでは「スレッド生成→待機→ハンドル解放」という一連の流れを明確な関数呼び出しで記述でき、Pthreadsとの対応関係を意識すると理解しやすくなります。
-
Windowsのプログラムをシステムトレイ(通知領域)に最小化する3つの方法
Windowsのインターフェースは、長年にわたって数多くの変遷を遂げてきました。スタートメニューのように多くのユーザーに愛された機能もあれば、Windows 8のMetroインターフェースのように不評だったものもあります。 最小化したウィンドウが並ぶタスクバーは、強い嫌悪感を抱かれる存在ではありません。しかし、起動しているプログラムが多いと、あっという間に窮屈になってしまいます。特に常時起動しておく必要のあるアプリケーションの中には、タスクバーのスペースを占有する必要がないものも少なくありません。 残念ながら、Windowsにはウィンドウを「通知領域」(旧称:システムトレイ)へ直接最小化する標
-
Windows Insider Programで役立つフィードバックを送信する方法
MicrosoftはWindows Insiderプログラムとフィードバックハブから大きな価値を得ていますが、実際に開発側で活用される有用なフィードバックを送信するのは決して簡単ではありません。本記事では、Microsoftの新しいCohorts(コホート)プログラムの概要、フィードバックハブの仕組みと課題、そして開発者が実際に改善に活かせるフィードバックの送り方について詳しく解説します。 フィードバックハブとは Microsoftはフィードバックハブを、良い意図のもとに開発しました。基本的な仕組みはシンプルで、Windows 10で何らかの問題に遭遇した際、フィードバックハブを使ってその問題