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が返る。

PHPでipがローカルかどうか調べる

filter_varでいろいろな条件を調べられる。メールアドレスとかドメインとか、あるいはboolとして1や”yes”,”on”なども調べられる。

この関数ではまずIPアドレスかどうかを調べて、つぎにそれがプライベートか予約されたアドレスかどうかの条件を追加して調べている。

FILTER_FLAG_NO_PRIV_RANGEを指定すると、プライベートでないものはfalseを返す。マニュアルによると以下。

Fails validation for the following private IPv4 ranges: 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16.

Fails validation for the IPv6 addresses starting with FD or FC.

FILTER_FLAG_NO_RES_RANGEを指定すると、予約されたアドレスでない場合はfalseを返す。マニュアル以下。

Fails validation for the following reserved IPv4 ranges: 0.0.0.0/8, 169.254.0.0/16, 127.0.0.0/8 and 240.0.0.0/4.

Fails validation for the following reserved IPv6 ranges: ::1/128, ::/128, ::ffff:0:0/96 and fe80::/10.

フィルタの一覧
http://php.net/manual/en/filter.filters.validate.php

フラグの一覧
http://php.net/manual/en/filter.filters.flags.php