Author Archives: admin

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

qmakeでlreleaseがエラー

64ビットWindowsを使っていて、32ビットのコマンドプロンプトやエクスプローラからqmake関係を起動するとおかしくなることがある。qmakeに限らず、64ビット環境での64ビットアプリと32ビットアプリでは環境変数などが一部異なるので、ビルド環境では64ビットの純正コマンドプロンプトやエクスプローラを使ったほうがよい。

コモンコントロールの適当なまとめ

コモンコントロールとはWindowsOSによって提供される基本的な機能を持ったウインドウ。ツリーやリストなど。コモンコントロールはバージョンアップが重ねられており、バージョンの違いでヘッダファイルにも違いが出る。開発環境と実行環境で違うバージョンがインストールされている場合もある。コモンコントロールはIEのインストールでバージョンアップされる。

https://msdn.microsoft.com/en-us/library/windows/desktop/hh298349(v=vs.85).aspx

実体

実体はComCtl32.dll。C:\Windows\System32\ComCtl32.dllにある。

ヘッダ

C言語のヘッダファイルでは_WIN32_IEにより、構造体などの定義が変わる。多くの構造体はそのサイズを持ち、この値がどんどん増えていく。この定数は_WIN32_WINNTの設定によって自動で設定される。_WIN32_WINNTを設定しなければ0x0500(version 5.80)になるようだ。SDKによって変わる。参照

コモンコントロールウインドウの作成

コモンコントロールのDLLがウインドウクラスを登録し、ユーザはこのクラスでCreateWindowExすることにより作成する。 InitCommonControlsEx()を呼ぶと、クラスの登録が行われるがDLLのロード時に行われるのかもしれない。

Visual Styles

Visual Stylesはコモンコントロールの表示スタイル(見栄え)を変える。

I18N

コモンコントロールの言語を変えるにはInitMUILanguage()を呼ぶ。

サイドバイサイド

ComCtrl32.dllはハードリンクされている。

WinSxSはサイドバイサイドのアセンブリが置かれているところで長い名前はComCtrl32.dllのアセンブリアイデンティを表している。アプリケーションが特定のバージョンのdllを読み込みたい場合はマニフェストにこのアイデンティを指定する。

このpragmaのつけたexeを起動すると、C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.16299.371_none_5d75084fa7e1cb96\comctl32.dllが使われる。このファイルはハードリンクをこの1つしか持っていない。ver6のコモンコントロールを使うにはマニフェストで指定するしかないことになる。

CygwinからWindowsアプリを起動する

explorerでカレントディレクトリを開く

これは普通に動くが、かなり特殊条件もあって動いている。explorerは起動されたプロセスが開くのではなかったり(開く場合もある)、”.”を理解してちゃんと開いてくれる。それにcygpath(cygwinの形態のパス変換)の問題もない。

TE32.exeでカレントディレクトリを開く

TEはプロセスがなければ自分で開くのでcygwinシェルから普通に起動するとシェルがブロックする。&をつけてバックグラウンドで動かしてもシェルがプロセスを管理しているため、cygwinの終了と同時に終了してしまう。nohubを使う手もあるかもしれないがここではスルー。

プロセスの起動はコマンドプロンプトのstartコマンドで行えばプロセス起動後すぐに終了するので上記の問題はない。しかしstartはビルドインプロセスのようでcygwinからは起動できない。そこでcmd /C startで起動すればいい。

パスの返還はcygwinのcygpath -waコマンドで行う。-aはフルパス、-wはWindows形態に変える。

よってカレントディレクトリをTE32.exeで開くには以下のように行う。

‘””‘はstartに””を送っている。startコマンドの性質上こうしている。

これでcygwinシェルから切り離されたプロセスと起動できたが何らかの環境変数などは継承しているかもしれない。

上記のコマンドはパスにスペースが含まれた場合を考慮していないので、その場合は””でくくらないとならないと思う。

qmakeの.proファイルの基礎

qmakeのproファイルの書き方

proファイルの名前

hello.proを作成すると、プロジェクト名がhelloになり出来上がる実行ファイル名もhello.exeになる。

ソースファイルを追加

SOURCES変数にファイルを追加する。

スペースで区切って複数指定してもいい、\ (バックスラッシュ)を行末につけて複数行にすることもできる。

ヘッダファイルを追加

HEADERS変数にファイルを追加する。

WindowsとLinuxで処理を分ける

{ は条件と同じラインに書かなければならない。

ファイルが存在しないときにエラーを表示する

デバッグモードを指定する

CONFIG変数にdebugと設定する。

WindowsのデバッグモードでqDebug()をコンソールに出力する

変数の設定と参照

変数は自分で書いてもいい。参照するには $$ を用いる。

インクルードパスの指定

コメント

# で始めるとコメントになる。

プロジェクトのタイプを指定(アプリかライブラリか)

TEMPLATE変数を使う。

  • app ⇒ アプリケーション
  • lib ⇒ ライブラリ

デフォルトはapp

CONFIGにいろいろ設定

  • qt ⇒ qtライブラリを使う
  • windows ⇒ WindowsのGUIアプリケーション
  • console ⇒ Windowsのコンソールアプリケーション

Qtライブラリを指定

QT変数を使う。

coreとguiはデフォルトで設定される。デフォルトから外したいときは += ではなく = を使う。あるいは -= を使う。

Featureを使う

Featureとは.prfで記述される特別な機能。CONFIGに機能を設定して使用する。

pkg-configを利用して、D-Busとoggライブラリを利用する。

Qt以外のライブラリの指定

ライブラリをつくる

ライブラリをつくるにはTEMPLATE変数にlibを設定する。そのうえでCONFIG変数でライブラリのタイプを指定する。

  • dll ⇒ ライブラリはDLL
  • staticlib ⇒ ライブラリはスタティックライブラリ
  • plugin ⇒ ライブラリはプリグイン

環境変数の取得

$$(ENVVAL)を使う。