Javascriptxinetdの罠コマンドプロンプトのログを取る(完結)コマンドラインで権限昇格を起こす(UAC)今更ながら大文字・小文字。Linux用だと思うんだけど)をリリースするという・・・。Serverである意味がないやん!サーバーOSに関して考えればOSを選んでからサーバーウェアを選ぶという時代じゃないですよね。実現したいサービスがあって、それを実現するためのサーバーウェアを選択して、それから最終的にOSを選ぶ・・・っていう。クラウドコンピューティングとか仮想化とか・・・、正直、OSなんか、もう、どれでもいいんですよね。なんかもうWindowsとかLinuxとかMacOSとかBSDとか、どれでも、いいんすよ。ま、こんなこと、今更感が満載なんですけどね。Xamarinも買収しましたよね。Linuxも含め、いずれはmonoプロジェクトも取り込んで、ネット上のクライアントとなるアプリ開発、サービス開発に必要なバックエンドソフトウェアと、必要なものがほとんどすべてマイクロソフトからリリースされることになったわけで。windowsVista以降では安易にスレッドを作るな!?TweetLinuxやBSDなどのUNIX互換のOSと違って、Windowsではスレッドを起こすのは普通に行われてることだと思います。Cランタイムライブラリの_beginthreadex関数を使うことになります。一方でスレッドを生成するのではなく、スレッドプールを利用する、というケースもあり、パフォーマンス的な事を考えれば、むしろこちらの方が多いかもしれません。APIというスレッドプールに関するAPIが使えます。いって、このAPI、よほど簡単なロジックでないと使えません。このAPIでキューに入れてしまうと、もう手が出ません。APIは使っちゃだめ!ですし・・・。結局、ちょっと凝ったことさせようと思ったら、自前でI/O完了ポートを駆使してスレッドプールを実装する他なかったと思います。Vista以降のNT6.x系のWindowsでは、より進化したスレッドプールAPIが追加されています。APIや_beginthreadex関数でスレッドを起こす前提のロジックでコーディングしちゃだめ。・・・スレッドを作ってそこにウィンドウを作成する、というようなケースには向きません。とどのつまり、プロセス開始から終了まで生存するようなスレッドの場合、スレッドプールに処理を投げる意味はありません。一つのスレッドの生成・削除が頻繁に行われるケースや、スレッドの生存期間が短いケース等でスレッドプールの恩恵を受けることができると思います。この新たに追加されたスレッドプールなAPI群は、スレッドの生成と管理をすべてWindowsが肩代わりしてマシンに積まれているCPUの数(コア数?)と負荷状態に応じて最適な性能を発揮できるようになっているようです(・・・なっているはずです)。したユーティリティアプリなんかで、単純な処理を非同期(並行)処理させる場合、TrySubmitThreadpoolCallbackもしくは、CreateThreadpoolWork/SubmitThreadpoolWorkでほとんど事足りると思います。CreateThreadや_beginthreadexのあの引数の多さにうんざりすることが無くなり、スレッドハンドルを管理するコード、同期のためにイベントオブジェクトを作成して待機するようなコード諸々を実装する手間が大幅に軽減されます。//スレッドプールにNUM回作業を投げる。パラメータが渡されるのでその点注意しなければなりません。//投げた作業が終了するまで待つ。閉じるのを忘れてました。CloseThreadpoolWork(pWork);}当然ですが、上記はXPでは実行できません。一連のスレッドプールに関するAPIは非常に強力で、使い勝手もいい。デフォルトのスレッドプールの動作が気に入らなければ、カスタマイズしたスレッドプールを利用することもできる。自分的に便利だと思ったのが、ReadFIle/WriteFileでI/O非同期処理に利用できる、CreateThreadpoolIo/StartThreadpoolIo。今まではI/O完了ポートで通知を受け取って・・・というようなコードを書いてましたが、Vista以降のOSに限定すれば、これらのスレッドプールAPIを使うことでコード量が減ります。APIを使ったディレクトリへの変更を監視するコードをスレッドプールを使ったコードに強引にリプレースしてみました。昔作った、WindowsXPで動作する、IO完了ポートとワーカースレッドを単純に作って利用したバージョン。std;//バッファサイズは適当です。_tprintf(TEXT("ディレクトリを指定してください。//終了通知を投げる。//ワーカースレッドはとりあえず2個。//FILE_FLAG_OVERLAPPEDを指定してディレクトリを開く。_tprintf(TEXT("ディレクトリのオープンに失敗しました。_tprintf(TEXT("I/O完了ポートの作成に失敗しました。//IO完了ポートに複数の(ディレクトリの)ハンドルを関連付ける場合に複数のワーカースレッドを作る方がいいかも。_tprintf(TEXT("監視用タスクが待機状態に入ります。//終了イベントがシグナル状態になるまで待機する。_tprintf(TEXT("監視用タスクが待機状態から解放され終了します。//FILE_NOTIFY_INFORMATION構造体をコピーする。コールバック関数に渡すNotifyParams構造体に値をセットしてコールバック関数をコールする。※コールバック関数が制御を返さないかぎりスレッドがワーカースレッドがビジーになる。//FILE_NOTIFY_INFORMATION構造体のFileNameメンバの終端をヌル文字で閉じる。//変更のあったファイルのフルパスを得る。1;}要点は、スレッドを作成して監視が終了するまで待機。APIをコールし非同期処理を継続します。続いて、上記をVista以降のスレッドプールのAPIを利用したバージョン。std;//バッファサイズは適当です。_tprintf(TEXT("ディレクトリを指定してください。//スレッドプールに作業を投げる。//終了通知を投げる。//投げた作業が終了するまで待つ。//FILE_FLAG_OVERLAPPEDを指定してディレクトリを開く。_tprintf(TEXT("ディレクトリのオープンに失敗しました。_tprintf(TEXT("監視用タスクが待機状態に入ります。//コールバック関数をコールしてディレクトリ監視を開始。//終了イベントがシグナル状態になるまで待機する。//現在キューに残っている作業をキャンセルする。//ハンドルを閉じる。_tprintf(TEXT("監視用タスクが待機状態から解放され終了します。//FILE_NOTIFY_INFORMATION構造体のメモリを確保してコピーしておく。//転送されたFILE_NOTIFY_INFORMATION構造体をコピーする。//ディレクトリ監視を開始するが、非同期なので制御が直に返る。//転送されたバイト数が0以上なら、何らかの処理をする。//ここでは変更のあったファイルを出力する。//FILE_NOTIFY_INFORMATION構造体のFileNameメンバの終端をヌル文字で閉じる。//変更のあったファイルのフルパスを得る。}}あまり違いがないように思いますが、スレッドを何個作るべき?だとか細々とした調整などが不要になり、何より_beginthread関数などのプリミティブなAPIを使わなくても良くなりました。以前なら、スレッド処理をラップする、なんらかのクラスライブラリが必須だったと思いますが、ちょっとしたツールを書くときはこれらの新しいスレッドプールなAPIを使えば良くなりました。ま、ちょっとしたツールを作るにはC#を使えば済む話で、わざわざC++を使う必要性があるとは思えませんが・・・。Zにインストールした。上で使うようにしました。遥かに使い勝手がいいし。推奨の?端末ソフトらしい。内ですべてを完結させたいところ。使ってみると、日本語もちゃんと表示されるし、最低限の機能を備えているので問題なし。Windowsのアプリですでに環境変数HOMEを設定していて、これは変えたくない。見ているらしく、デフォルトでホームディレクトリが、Windowsの%USERPROFILE%になるみたい。設定することで解決してたんですが・・・。環境変数HOMEをバッチファイルに埋め込めばいいんだけど、それだといちいちコンソールウィンドウが立ち上がってブサイク。力を借りて下記のような起動スクリプトを作ってスタートメニューに登録。非WIndows環境はすべてcygwinにしてしまいました。指定しないと・・・んーーーなんか挫折しそう。