複数の子スレッドが存在する場合、優先順位を指定することができます。
| THREAD_PRIORITY_HIGHEST | (+2) |
| THREAD_PRIORITY_ABOVE_NORMAL | (+1) |
| THREAD_PRIORITY_NORMAL | (0) |
| THREAD_PRIORITY_BELOW_NORMAL | (-1) |
| THREAD_PRIORITY_LOWEST | (-2) |
| THREAD_PRIORITY_IDLE | (1) |
| THREAD_PRIORITY_TIME_CRITICAL | (15) |
の7つがあります。()内の数値は+であれば相対優先度を上げ、マイナスであれば 優先度を下げることを意味します。
最後の2つは、優先度そのものを指定します。
スレッドに優先順位を指定するにはSetThreadPriority関数を使います。
BOOL SetThreadPriority( HANDLE hThread, // スレッドハンドル int nPriority // スレッドの相対優先順位値 );dwDesiredAccessに、アクセス権を指定します。
これには、
| SYNCHRONIZE | 待機関数で使用できるようにする |
| THREAD_ALL_ACCESS | すべてのアクセスフラグを獲得します。 |
| THREAD_GET_CONTEXT | スレッドハンドルをGetThreadContext関数で使えるようにします。 |
| THREAD_QUERY_INFORMATION | スレッドハンドルで終了コードなどの情報を読み取れるようにします。 |
| THREAD_SET_CONTEXT | スレッドハンドルをGetThreadContext関数で使えるようにします。 |
| THREAD_SET_INFORMATION | スレッドハンドルで特定の情報を設定できるようにします。 |
| THREAD_SET_THREAD_TOKEN | スレッドハンドルをSetTokenInformation関数で使えるようにします。 |
| THREAD_SUSPEND_RESUME | スレッドハンドルをSuspendThread関数や、ResumeThread関数で使えるようにします。 |
| THREAD_TERMINATE | スレッドハンドルをTerminateThread 関数で使えるようにします。 |
などがあります。
bInheritHandleには、取得したハンドルを新しいプロセスに継承できるかどうかを指定します。
dwThreadIdには、スレッドIDを指定します。
関数が成功するとスレッドハンドルが返されます。 失敗するとNULLが返されます。
では、サンプルのプログラムを見てみましょう。
// priority.c
#define MYMAX 3000
#include <stdio.h>
#include <process.h>
#include <windows.h>
unsigned __stdcall mythread0(void *);
unsigned __stdcall mythread1(void *);
unsigned __stdcall mythread2(void *);
unsigned __stdcall mythread3(void *);
LONG lAdd = 0;
int n = 0;
int main()
{
HANDLE hTh[4];
DWORD dwID[4];
int i;
_beginthreadex(
NULL ,
0,
mythread0,
NULL,
CREATE_SUSPENDED,
&dwID[0]
);
_beginthreadex(
NULL,
0,
mythread1,
NULL,
CREATE_SUSPENDED,
&dwID[1]
);
_beginthreadex(
NULL,
0,
mythread2,
NULL,
CREATE_SUSPENDED,
&dwID[2]
);
_beginthreadex(
NULL,
0,
mythread3,
NULL,
CREATE_SUSPENDED,
&dwID[3]
);
hTh[0] = OpenThread(SYNCHRONIZE | STANDARD_RIGHTS_REQUIRED | THREAD_SUSPEND_RESUME | THREAD_SET_INFORMATION, TRUE, dwID[0]);
hTh[1] = OpenThread(SYNCHRONIZE | STANDARD_RIGHTS_REQUIRED | THREAD_SUSPEND_RESUME | THREAD_SET_INFORMATION, TRUE, dwID[1]);
hTh[2] = OpenThread(SYNCHRONIZE | STANDARD_RIGHTS_REQUIRED | THREAD_SUSPEND_RESUME | THREAD_SET_INFORMATION, TRUE, dwID[2]);
hTh[3] = OpenThread(SYNCHRONIZE | STANDARD_RIGHTS_REQUIRED | THREAD_SUSPEND_RESUME | THREAD_SET_INFORMATION, TRUE, dwID[3]);
SetThreadPriority(hTh[0], THREAD_PRIORITY_IDLE);
SetThreadPriority(hTh[1], THREAD_PRIORITY_LOWEST);
SetThreadPriority(hTh[2], THREAD_PRIORITY_HIGHEST);
SetThreadPriority(hTh[3], THREAD_PRIORITY_TIME_CRITICAL);
for (i = 0; i < 4; i++)
ResumeThread(hTh[i]);
WaitForMultipleObjects(3, hTh, TRUE, INFINITE);
for (i = 0; i < 4; i++)
CloseHandle(hTh[i]);
return 0;
}
unsigned __stdcall mythread0(void *lpx)
{
int n = 0;
while (lAdd < MYMAX) {
lAdd++;
n++;
printf("thread0--%d\n", lAdd);
Sleep(10);
}
printf("thread0は%d回\n", n);
return 0;
}
unsigned __stdcall mythread1(void *lpx)
{
int n = 0;
while (lAdd < MYMAX) {
lAdd++;
n++;
printf("thread1--%d\n", lAdd);
Sleep(10);
}
printf("thread1は%d回\n", n);
return 0;
}
unsigned __stdcall mythread2(void *lpx)
{
int n = 0;
while (lAdd < MYMAX) {
lAdd++;
n++;
printf("thread2--%d\n", lAdd);
Sleep(10);
}
printf("thread2は%d回\n", n);
return 0;
}
unsigned __stdcall mythread3(void *lpx)
{
int n = 0;
while (lAdd < MYMAX) {
lAdd++;
n++;
printf("thread3--%d\n", lAdd);
Sleep(10);
}
printf("thread3は%d回\n", n);
return 0;
}
各スレッドは、共通のグローバル変数lAddにアクセスしてその値を1増やします。これが、MYMAXに達するとスレッドは終了します。
共通変数に、各スレッドが勝手にアクセスするのでおかしなことが起ることもあります。 (lAddの値が重複するなど)
各スレッドが何回共通変数にアクセスして値を増やしたかを最後に表示するようにします。
当然優先順位の高いスレッドが多くアクセスするはずです。
実験してみるとわかりますが、マシンスペックに余裕がある場合はほとんど差がつきません。動作中に、重たいソフトを動かすなどすると、優先順位の高いスレッドほどアクセス回数が多くなります。
Update May/17/2005 By Y.Kumei