スレッドと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を変更可能。

  1. Asmモジュール等で対象関数を作成
  2. 対象スレッドのIDを何らかの方法で取得
  3. 対象スレッドを開き、Suspend
  4. GetThreadContext(.ContextFlags = CONTEXT_CONTROL)
  5. Eipをpushする(EspをずらしてEspの領域に入れる)
  6. Eipを対象関数にして、SetThreadContext
  7. Resumeすると該当スレッドで対象関数が実行され、実行後戻る

必要な権限:THREAD_SUSPEND_RESUME|THREAD_GET_CONTEXT|THREAD_SET_CONTEXT
自スレッドで実行したい場合、上記処理をするスレッドを起動すればよい。
待ち合わせが必要なら、SleepかEvent等を使う。


しかし、、、Windows8とか言ってる時代に、何を探求しているのだろう?