phpはウェブサーバーと一体化している

無限ループするphpスクリプトが埋め込まれたhtmlをポストしても、なぜかプロセスにphp.exeというのが表れない。スクリプトにgetmypid()を入れてプロセスを特定してみたらhttpdになっている。つまりApacheである。

www.atmarkit.co.jp

PHPプログラムを実行する方法はCGIプログラムとして実行する方法と、Apacheモジュールとして実行する方法の2種類から選ぶことができます。この2種類の決定的な違いは動作速度です。CGIプログラムとして実行する場合に比べて、Apacheモジュールとして実行する場合の方が遥かに高速なのです。

 その理由は、CGIプログラムとして実行する場合は、PHPプログラムが呼び出されるたびにプロセスが1つ立ち上がることにあります。これに対し、Apacheモジュールとして実行する場合は、Apacheのプロセスの中で実行されるため余分なプロセスを立ち上げる必要はありません。

20年前の文章だが参考になった。phpというのはapacheに組み込まれて一体となっているようだ。

C言語のwait()とPythonのsubprocess.Popen.wait()

C言語のwaitpid(&status)は、特定の子プロセスを待つ関数であるというよりかは、特定の子プロセスを待つという動きを登録する関数であるといったほうが正しい。

pid_t pid;
int status;
if ((pid = fork()) < 0)
    error();
else if (pid == 0)
    exit(7);

if (wait(pid(&status) != pid)
    error('wait error');

aes256bit.hatenablog.com

バッチファイルの闇

Windowsコマンド、本当に融通が効かなくてつらい。にわかで操作できるものではないようだ。いろいろメモしておく。

1、変数への代入は基本文字列としてあつかわれる。すべては文字列。set x=3 の場合3は文字列。そして余計なスペースをいれない。これはシェルでもおなじ。

2、数値計算を行いたいときはaオプション。set /a x=3+4 たぶんこれでいい。

3、タスクスケジューラ-からpythonスクリプトを実行するときは、svchost.exeという強そうなコマンドからpython.exeがスポーンされる。

4、バッチファイルを実行するのは、コマンドを順番に実行するのと同じことである。新しいcmdプロセスが生成されたうえでコマンドがスポーンされるわけではなく、既存のcmdプロセスからスポーンされるだけ。(その点Linuxではバッシュファイルを実行すると、新たにbashが起動されてそのうえでコマンドが実行されていく。)

5、start command/batch.bat は、新しくcmd.exeがフォークされてからそこでコマンドが実行される。Linuxでいうところのスポーンに相当する。start /wait の場合は、子プロセスの終了を回収する。大事。start /bはバックグラウンドのbかとおもいきや、親プロセスと同じ端末を共有する。ややこしい。call commandはフォアグラウンドでコマンドが実行される。つまりふつうにcommandを入力するのとおなじ。call batch.bat も新しくcmd.exeがフォークされるわけではない。batch.batを実行するのとおなじ。 しかしブラウザやエディタをコマンドプロンプトからcallで呼び出しても、なぜか制御はうつらない。バックグラウンドで起動されたような感じになる。よくわからない。

6、batchファイルの中のfor文の変数は%%iというふうに%を2つ必要とする。ただのコマンドの場合は%iというふうにひとつでいい。

7、shell script のgrepにあたるコマンドは、findstrという。

8、最後にして最大の関門は遅延変数。いいかげんにしろ。自らのプロセスIDを取得することすら容易ではない。

for /f "usebackq tokens=2 delims=," %%i in (`tasklist /v /fo csv ^| findstr "cmd.exe" ^| findstr "THIS"`) do (
    set thiscmdpid=%%i
    set thiscmdpid=!thiscmdpid:~1,-1!
    echo !thiscmdpid!
)
title THIS
call main

なにかしらのプロセスのIDを外部プロセスから特定したかったのだが、親子関係にない場合どうすればいいのかわからなかった。苦肉の策としてtitle コマンドで名前をつけることにした。上記のバッチファイルを実行すると、現在同じバッチが実行されているプロセスを探知することができる。それにしても遅延変数を知らなかったので、なにか実行するたびに結果が規則的に変わっていくので困った。


qiita.com

最終的にPowershellを使うと解決することが判明した。

stackoverflow.com

これ自分の質問。英語版のstuck overflowは本当にありがたい。

web経由で実効されるバックエンドプロセスの実効ユーザーはだれ?

windowsのtimeコマンド、1桁時台のときは0ではなくスペースが入る。時間を0から9までの文字だけで表現できないので、よろしくない。


WindowsLinuxでプロセスについて理解を深めている。ところでひとつ疑問。プロセスには実ユーザーや実効ユーザーIDというのがあって、これはログインしてそのコマンドを実行するユーザーがそのプロセスの実ユーザーになるのは理解しているのだが、ウェブ経由で有象無象の第三者から指示されてコマンドが実行されたとき、そのコマンドプロセスの実ユーザーは一体誰になるのだろうか。

もうひとつの疑問。端末からコマンドラインpythonスクリプトを実行する時は、仮想環境を指定してそこで実行することができる。しかし、ユーザーがウェブ経由でスクリプトを実行するときはどうやって仮想環境を指定すればいいのか?モジュールと仮想環境をあらかじめ紐づけるような設定ファイルみたいなものがあるのだろうか?

オンラインミーティング

オンラインミーティングがとても楽しい。いろんな会社のひとが集まってひとつのプロジェクトについて進捗や意見を交わし合う。自分が発言できるのはごくごくわずかな時間に限られているが、いつも発言するたびに場が少し固まっている。おそらく頓珍漢なことを言っているんだろう。そのたびに恥ずかしくて恥ずかしくて衝動的に回線をオフにしたくなるのだが、じっと耐え忍ぶ。実はこういう機会を待っていたともいえる。ひとりで学習していたらなかなかすることができない経験だ。たくさんの専門家の方たちと同じ場を共有できる。全く理解できない言葉がたくさん飛び交っているが、それをひとつずつ咀嚼しているような時間はない。圧倒的な情報の洪水だ。その中で今の自分のベストをしぼり出す。そしてはじかれる。恥をかいたときの記憶は、その克明な場面状況とともに長期的に定着する。今のうちにかけるだけの恥はすべてかいておこう。そのミーティングメンバーの中にひとりどうしても認めてもらいたいひとがいる。UNIXの伝道者のようなひとだ。

話は変わるが、今までいろんなひとに「どんな仕事をしてるの?」と尋ねてきたが、いまいちピンとこなかった。自分は仕事をするようになって、この感じを仕事をしたことのないひとに伝えるのはとても難しいなと思うようになった。難しい理由は「仕事中は時間感覚が変わるから」である。仕事をしているときは時間が圧縮されている。8時間が一瞬で過ぎ去っていく。歩いている人には車に乗っている感覚がわからないということ。その圧縮された時間の中で、目指すものに近づいていく。目指すものがわからないときは、目指すものを明確にする。今のままではそこにたどりつけないなら該当する知識や技術を身につける。そうやっているうちに時間は過ぎ去っていく。仕事をするというのは、自分にとって新しい生活スタイルで、今はとても楽しい。

作業を割り振ってもらえるということは

11月から契約社員になった。いま複数の会社が連携しているひとつのプロジェクトの一員として、アプリケーションを作っている。プロジェクトと大袈裟に言ったが、自分にはほんのわずかな役割しかない。テストコードを含めても数百行で済んでしまうようなものだ。上司が自分の力量を冷静に見据えたうえでふさわしい仕事量を割り当ててくれたのかもしれない。会社ごとに縄張りというか分担があり、ひとつの会社の中にも作業の分担がある。こうやって仕事を分かち合っていくのは不思議だ。本来なら自分のような初心者はマイナスの要素でしかないはずなのに、わざわざ作業を割り振ってもらえる。自分は作業の中でいろいろ学ぶことができる。経済学にはこういう比較優位というアイデアがある(すべてのタスクを能力の一番高い人が受け持つのは効率的に見えて実は効率が悪い。能力が低い人に得意なタスクを分担させることで全体的な効率を図ることができる)が、このアサインの文化はけっして比較優位だけで説明できるものではない。人を育てるという発想が明確に存在している。実際には誰からも何も教えてはもらえない。コードの書き方も、アプリケーションのディレクトリ構造も、データベースのテストの仕方も、なにもかもが我流である。しかし仕事を割り振ってもらえるというのは、これらを差し引いても本当に大きい。贅沢は言っていられない。会社に入ってよかったと思った。


ところではじめてPostgreSQLというデータベースを扱うことになった。今まではMysqlSqliteしか扱ったことがなかったから新鮮だが、Mysqlとおなじでサーバークライアント方式のソフトウェアである。JohnsonのUNIXの本を熟読しているおかげで、サーバークライアント方式の意味がどんどんわかるようになってきた。サーバークライアント方式というのは、ブラウザとウェブサーバーのようなリモートの関係だけではない。ひとつのホストの中にもサーバーとクライアントは同居しうるということ。そして原始的なサーバークライアント方式というのは、クライアントがフォークすることでサーバープロセスを作り出しているのだということ。それが進化してサーバーはデーモンプロセスになった。そしてクライアントプロセスのリクエストごとにサーバー自身をフォークさせることでマルチクライアントに対応することができるようになった。データベースのサーバーというのは、mysqldであったり、psqld(だったかな?)というようなデーモンプロセスである。そしてクライアントはコネクターとよばれている。データベースをいろんな言語で操作するために、コネクターはいろんな言語に対応している。

linuxのcrontabはwindowsのschtasks

LInuxシェルスクリプトファイルに相当するものは、windowsではバッチファイルとよばれる。拡張子は.batや.cmdであることが多い。このバッチファイルを用いてwindowsコマンドを実行していく。

ところで今日はexecl()関数を復習していたのだけど、このあたり重要なわりに理解が曖昧な部分が多いことが判明した。

if (execl("/bin/echo", "echo",  "hoge1", "hoge2", (char *) 0) < 0)

このように実行ファイルの場合はわかりやすい。

if (execl("/home/shinji/unix/test", "unix",  "hoge1", "hoge2", (char *) 0) < 0)

testファイルが解釈実行ファイルの場合は、少し複雑である。この場合、解釈実行ファイルの第一行目に着目する必要がある。

#! /bin/python foo

と書いてあったなら、これはpythonスクリプトファイルである。つまり実際のところは、

python foo test hoge1 hoge2

というコマンドが実行されることになる。


Linuxのcrontabコマンドに相当するものは、windowsではschtasksコマンドである。これで定期的に行われるタスクを登録したり変更したりすることができる。

crontab -l # タスクのリストを表示する
crontab -e # タスクファイルを編集する

これに相当するコマンドは以下のとおり。

schtasks /query /tn test
schtasks /change /tn test

いま実務で簡単なタスクスケジュールの実装をやっている。今までのように「とりあえず動けば合格でいいか」では済まされない。やるべきことはおそらく3つ。実行権限についての考慮。例外処理。そしていろんな可能性を考慮して徹底的にテストプログラムを書くこと。