時計について教えてください (2) [1996.11]

時計が計るのは時刻と時間の二つだが,ここでは時間.使われ方は,主に,指定した時間がたったら何かやる,指定した時間は何もしない,の二つだろう.前者は alarm 機能,後者は sleep にあたる.内部的にはどちらも指定時間後にシグナル (SIGALRM) を発生させるタイマー機能を使う.

指定時間後に何かやるときには,C の関数を書いて SIGALRM シグナルのハンドラにその関数をセットして alarm を実行する.時間は alarm の引数で指定する.指定時間後にハンドラ関数が実行される.ハンドラ関数は,シグナル割り込み禁止状態でなければ,それまでどんな処理をしていたかにまったく関わらず呼び出される.ハンドラで全体の処理と全く独立の仕事をしたりするのでなければ,ハンドラ関数が処理を引き継ぐような書き方はしないほうがいい.大域変数をセットする,longjmp で全体の処理のうちのそれように設定した個所に制御を移す,といったスタイルにしよう.また,ネットワークからの入力を待っている read の最中に指定時間になったとき,ハンドラが呼び出された後の動作が UNIX によって異なるので注意する.ハンドラ関数から戻ったあと,そのまま read を継続するシステムと,read からリターンして,errno にシグナルを受けたことを記しておくシステムとがある.確認しよう.なお select か poll システムコールが実装されていれば,入出力とタイムアウトを組み合わせるのに便利に使える.

指定した時間何もしない sleep 機能も他のプログラムと通信したり,利用者とのインタフェースの場面ではよく使われる.時間を稼ぐのに,for 文でループを回すようなことはしてはいけない.内部的には,alarm を使って時間を指定し,シグナルが来るまで CPU を明け渡す sigpause といったシステムコールで実現されている.alarm を同じタイマーを使うが,二つが共存するようにライブラリが面倒を見ている.sleep で指定する時間は普通1秒が単位である.1秒より短い時間待つには usleep (u はμのこと) を使う.これがなければ select や poll のタイムアウト部だけを利用するの手だ.しかし,時間の最小単位はシステムごとに決まっているし,プロセスのスケジュール等の影響も受ける.あまり短い時間は正確ではないことを憶えておこう.

UNIX は実時間制御に向いていないと言われる.入出力待ちのプロセスほど優先度が高くなるスケジューリングが示すように,UNIX はまず人間のためのシステムなのだ.


パイプについて教えてください [1997.1]

マウスとウィンドウは動きが目で見えてわかりやすいのは確かだが,昔ながらのコマンドシェルで正規表現と for (foreach),パイプを組み合わせて処理を一気に片付けるときの爽快さは得られない.

パイプは書込み用と読み込み用の二つのファイル記述子の組である.パイプに書いたデータはそのパイプから順に読むことができる.パイプは pipe システムコールで作成する.パイプにためられるデータは 4Kbyte 程度の固定量である.ひとつのパイプの書き口と読み口を二つの別のプロセスで使えば,それらのプロセス間でデータが渡せる.パイプを共有するわけだが,これは,パイプを作ってからそのプロセスが fork によって分かれることで実現する.fork や execute 系のシステムコールではファイル記述子の結合状態が保持されるのが UNIX の特徴である.逆にこれ以外でパイプを共有する方法はない.すでに存在しているプロセスの間をパイプで通信することはできない.シェルでのパイプは,指定されたコマンドの標準出力と標準入力を作成したパイプのファイル記述子で置き換えることで実現する.伝統的 UNIX では記述子複製用の dup システムコールを使うというトリッキーな置換えをしていた.

パイプで通信をしているとき,その読み側のプロセスが先に終了してしまった場合を考えよう.書込み側プロセスにとって,これは端末やファイルに書き出しているときには起こらない事態である.これが起きると,書込み側プロセスには SIGPIPE のシグナルが発生する.エラーメッセージとしては Broken pipe が表示される.日本語システムで,このメッセージを「パイプの崩壊」と表示するのはなんとも言えなかった.

パイプでネットワークを越えることもできる.もちろんコマンドの機能を使うのだが,例えば次のようにする.

tar cfB - . | rsh host '(cd todir; tar xfBp -)'

tar のオプションに種類があるので,このままでは動かないことがあるが,tar でカレントディレクトリ以下のファイルをすべて標準出力に書き出し,rsh で遠くのホストの tar にパイプで接続する.rsh は標準入出力をそのまま接続するし,cd はシェルの内蔵コマンドなので,これで tar 同士が繋がるのだ.パイプのように洗練された機能があってこそ,UNIX は生き長らえているのだ.


† これも今時は ssh. rsh のところを ssh に置き換えればそのまま有効.[2003.5.31]


プログラムを書きたいのですが [1997.2]

手元にある bit 誌のなかでは,UNIX は 1976年2月号で紹介されている.PDP-11 で UNIX が動いたとされているのは 1971年2月だ.以来,UNIX 上では大量のプログラムが書かれてきた.まだ書くプログラムがあるのだろうか.それが,やはり,ある.といっても,UNIX のコマンド群の利用を図るところから始めればずっと手間が少ない.

UNIX ではプログラムを使い捨てにせず,プログラマ間で共有していくことが容易に実現できる.逆に,プログラムを書くときにも,それが他のコマンドと組み合わせて使えるかどうかに気を配るべきだ.入出力がひとつづつであれば,フィルタとしてパイプで繋げるだろう.それなら,本来の出力以外のメッセージはけっして stdout に書いていけない.代わりに stderr を使うべきだ.そのプログラムが同時に複数走る可能性を常に考えよう.作業用のファイルが必要なら,mktemp といったライブラリ関数を使って,ユニークな名前を作ろう.signal をキャッチして,後始末を行儀よくやろう.高速化のため /tmp をメモリに割り当てているかもしれない./tmp にあるファイルはメモリそのものを消費しているのだ.UNIX のツールを最大限に利用しよう.例えば make. make を C プログラムの作成にしか使わないのはもったいない.sh と awk で処理ができる場合も,Makefile で sh, awk を起動しよう.その際,出力の依存ファイルとして入力ファイルとともに使った sh スクリプト,awk スクリプトを記述しておこう.出力フォーマットを変えたといったとき,再実行が実に簡単になる.コマンドの組み合わせも,シェルでコマンドヒストリを編集していたのでは後になって忘れてしまう.Makefile を書けば走るドキュメントになる.なお,awk はオリジナルのものより,nawk とか gawk 等,拡張されて連想配列が使えるものが記述力が格段に高まっている.

ネットワークを活用しよう.プリントアウトのコマンドが備わっているマシンがあれば,rsh で呼び出すことでなんの設定もなくプリンタが使用できる.C からなら,popen で rsh を走らせれば,ネットワークプログラミングをまったくしないでもリモートマシンのプログラムとの通信が確立する.サーバ / クライアントプログラムも一瞬のうちに完成だ.

自分のマシンのライブラリ,使える機能は普段から調べておこう.自分の大きな財産となる.


ネットワークプログラムの注意点は? [1997.4]

あまりに分野が広く,かつ注意点がいくらでもあるので,UNIX かつ UCB ソケットかつ TCP/IP くらいまで限定して初級レベルでの注意点をあげておこう.キーワードは man ページ等で確認してほしい.


UNIX カーネルのソースを読みたいのですが. [1997.5]

Configure と make all はもういいね.いくらやってもきりがないし,カーネルを読んだり書いたり! するほうがずっと面白い.

まずソースを探そう.ソースライセンスを得ているサイトなら,/usr/src/sys あたりにあるだろう.SystemV 系か Berkeley UNIX かはそれほど気にしなくていい.UNIX の根の部分は20年前からそれほど変わってはいない.なければ自分で購入しよう.最近は雑誌の付録の CDROM に FreeBSD が一式はいっていたりする. 読むには (走らせるにも) これで十分だ.計算機が手元になかったら (いや,あっても),ソース解説の本がいい.最近出版された "Lions' Commentary on UNIX 6th Edition, with Source Code" (邦訳) はたいへん有名な文献だ.1976年5月24日の昼頃プリントアウトされたカーネルソースに行番号付きで解説がついている. UNIX の版は古いが,そのぶん分量が少ないので挫折なく読める.C 言語のシンタクスがやや違うが,それも歴史だ

読み始めるには,例えば exec 系のシステムコールあたりがいいだろう.exec は引数がファイル名であるから,システムコールの仕組みからパス名の扱い,ファイルシステム,メモリ管理,ファイル入出力まで関連がつく.いろいろな構造体が重要な役割をもっているから,ヘッダファイルにはすぐにアクセスできるようにしておこう.特に,user と proc は重要だ.読み進むうち,namei の i が i-node, suword の u は user, と想像が働くようになる.ここまでくればしめたものだ.プロセススイッチ,シグナルといった躍動感あふれるコードにも挑戦しよう.

ハードウェアの説明書もほしい.特にそのソースの CPU の説明書は必須だ.割り込みやトラップといった機能の理解だけでなく,C の関数呼び出しのシーケンス,スタックフレームの構造を知るためだ.プロセススイッチのコードはこれなしには読めない.

一般的なカーネル構造の解説は数多く出版されている.共立出版UNIX カーネルの設計 The design of the UNIX operating system は重要だ. ちょっと古いが,中村明著「オペレーティングシステム構築法 UNIX 詳説 - 構造編 -」丸善 1986 ISBN 4-621-03097-3 も秀逸だ.

できたら本より実物がいい.ソース付きのパソコン UNIX を,そのソースをコンパイルしたカーネルで走らせよう.printf をいれたりしてみよう.カーネルもプログラムだ.


"Lions' Commentary on UNIX 6th Edition, with Source Code" については 2238クラブ が深い.[2003.8.8]


PC で動く UNIX があると聞きましたが? [1997.7]

計算機としてのパーソナルコンピュータは,CPU, メモリ量,外部記憶,何をみても少し前のワークステーション,もう少し前のミニコン,昔の大型機をはるかに越えた能力をもっているのは誰の目にも明らかだ.20年前のミニコンで動いていた OS は,今の PC で立派に動く.種類もたいへん多い.売り物で完全なサポートのつくものから,雑誌の付録の CDROM にソース,アプリケーション一式含まれているものまでさまざまだ.ここでは,この無料のほうについて述べる.bit 誌の 1997年5月号に PC UNIX の特集が組まれているので,これもぜひ読んでいただくとして注意点を書こう.なお回答子は FreeBSD (RELEASE-2.1.7.1, RELEASE-2.2.2) しか使ったことはない.個人レベルで使うぶんには十分な速度と安定性を備えていて,満足して毎日使用していることをまず記しておく.


† 2003.6.2 現在は FreeBSD 4.8-RELEASE を使っています.


   タイトル一覧  ホーム
webmaster