[C#] プロセス・スレッドを実行させるCPUコアを制限する

まえおき

C#で書いたプログラム中で、コードの一部を実行させるCPUコアを制限させたい場面に遭遇したので、方法を調べてみた。以前に同内容を調べた際、C/C++ではSetThreadAffinityMask(),SetProcessAffinityMask()を呼び出せば可能*1ってのは分かったので、今回はそれ以外の方法も探してみた。

現在実行中のスレッドにAffinityMaskをかける

現在実行中のハードスレッドを調べる方法が見つからなかった*2ので、P/Invokeを利用してC/C++と同様の方法を採用。Win32 APIの宣言部分は、PINVOKE.NETに載ってのをそのまま流用しました。

SetThreadAffinityMask
http://www.pinvoke.net/default.aspx/kernel32/SetThreadAffinityMask.html
GetCurrentThread
http://www.pinvoke.net/default.aspx/kernel32/GetCurrentThread.html

話は脱線するけど、このサイト、Win32 APIの宣言部分を大量に網羅してる上、直で宣言部分を呼び出せるVS用のアドインも配布してるのでめちゃくちゃ便利かも。

で、実際のコードは、

[DllImport("kernel32.dll")]
static extern UIntPtr SetThreadAffinityMask(IntPtr hThread, UIntPtr dwThreadAffinityMask);

[DllImport("kernel32.dll")]
static extern IntPtr GetCurrentThread();

を適当な場所に書いて、

SetThreadAffinityMask(GetCurrentThread(),(UIntPtr)1);

ってやればOKでした。お手軽。

現在実行中のプロセスにAffinityMaskをかける

System.Diagnostics.Processクラスに、プロセスを扱う手段が用意されていたのでそれを利用しました。

System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess();
process.ProcessorAffinity = (IntPtr)1;

とか書いてやればOK。やっぱり標準で用意された方法で済ませられるってのは便利だなぁとか思った。

*1:http://d.hatena.ne.jp/kaminarioyaji/20081206/1228551389

*2:ProcessThread.ProcessorAffinityを使えばスレッドにAffinityMaskをかけれるので、現在実行中のスレッドを取得する方法も探せばあるような・・・。