スレッドとCPUの関連について
スレッドについて気になったので、調べてみた。
- UWSCのスレッドは、ネイティブスレッド(GetCurrentThreadIdで判明)
- スレッドの動いている(瞬間の)CPU番号は、GetCurrentProcessorNumberで取得可能。ただしVista以降。XPは後述
- プロセスのCPU割り当ては、タスクマネージャーのプロセスタブで「関係の設定」からできる
- Vista以降は、コマンドプロンプトのstartコマンドでも可能
- Win32API的には、SetProcessAffinityMaskで行う
- スレッドのCPU割り当ては、SetThreadAffinityMask
- CPUの数は、GetSystemInfoで取得できる(1CPU 2コア Hyper-threadingの場合、4)
- 1コア複数スレッドの場合、GetLogicalProcessorInformationで判定可能。ただしVista/XPx64以降
XPでのCPU番号取得
ただし、Pentium4以降のCPU限定とのこと
Windowsで実行中のスレッドが動作している論理CPU番号を取得するには - とぴやまのブログ
DWORD WINAPI GetCurrentProcessorNumberForXP(void) { _asm { mov eax, 1; cpuid; shr ebx, 24; mov eax, ebx; } }
これをするUWSCスクリプトをAsmモジュールを使って書いてみたけど、、、
スレッド起動して実施するので、無意味だった、、、。
CALL Asm DIM no, addr = Asm.Set("VYvsU7gBAAAAD6LB6xiLw1tdwgQA") PRINT Asm.Run(addr, 0, no) Asm.Free(addr)
まあでも、どのCPUに割り当てられるかはわかる。
それは、GetProcessAffinityMaskでわかるけど。
未確認事項
いわゆるプログラムカウンターは、Intel系ではEip。
GetThreadContext & SetThreadContext でスレッドのEipを変更可能。
- Asmモジュール等で対象関数を作成
- 対象スレッドのIDを何らかの方法で取得
- 対象スレッドを開き、Suspend
- GetThreadContext(.ContextFlags = CONTEXT_CONTROL)
- Eipをpushする(EspをずらしてEspの領域に入れる)
- Eipを対象関数にして、SetThreadContext
- Resumeすると該当スレッドで対象関数が実行され、実行後戻る
必要な権限:THREAD_SUSPEND_RESUME|THREAD_GET_CONTEXT|THREAD_SET_CONTEXT
自スレッドで実行したい場合、上記処理をするスレッドを起動すればよい。
待ち合わせが必要なら、SleepかEvent等を使う。
しかし、、、Windows8とか言ってる時代に、何を探求しているのだろう?