IO優先度を変更する

優先度と言えば通常はCPUの優先度で、これを低く設定するとそのプロセスはCPUを使いづらくなる。あるメインのタスクがあってそれを重点的にやりたい場合、このタスクの優先度を上げて、これとは別の忙しそうなタスクの優先度を下げる。こうすることによりメインのタスクは他のタスクに邪魔されずにスムーズに作業が進む。

しかしCPUの優先度を下げてもそのプロセスが大量のデータをハードディスクでやり取りしているとうまくいかなくなる。メインタスクがハードディスクにアクセスしようとしてもCPUの優先度はこの場合関係がないので、待たされることになり作業が捗らない。

そこで使うのがIOの優先度なのだが、WindowsにしてもLinuxにしてもドキュメントやAPI整備が整っていない。

Windows

もっともよくドキュメントが整備されているのがSetPriorityClass()で指定できるバックグラウンド設定だ。この設定だけは他の設定と違い、BEGINとENDで開始と終了を指定する。なぜこんなことになっているのかといえばバックグラウンドの設定だけはCPUだけじゃなくIO優先度や他の優先度(メモリ)も変更するからだと思われる。しかし制限もあり、バックグラウンドの場合だけは他のプロセスの設定を変更できない(実際にエラーになる)。

そこでこれを実現したいのだがドキュメントがないのでネットで調べるとntdll.dllで定義されるNtSetInformationProcessを使うことがわかった。

この関数は挙動が不明なところがあって、デバッガでステップオーバーすると失敗するが、普通に実行すると成功したりする。この関数でメモリとIOの優先度を変更できる。

IOの優先度を最低にするには以下のように行う。

0が返ってくれば成功。hProcessをOpenProcess()で取得する場合はフラグにPROCESS_SET_INFORMATIONを指定して開く。

Linux

Linuxの場合はコマンドのioniceがあるので、このソースを見ればいい。しかしこれもドキュメントやヘッダファイルがないようである。

ioniceから持ってきたであろう上のソースをコピペして以下のように呼ぶ。

ioprioは2つの値DATAとCLASSから構成されていてCLASSで優先度を指定する。DATAはスルー。Linuxの場合、優先度をある程度上げるときはroot権限が必要な模様でその失敗の場合-1が返る。

Leave a Reply

Your email address will not be published. Required fields are marked *

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)