シグナルハンドラ

シグナルハンドラ内では、malloc()やprintf()系が使えず、thread safe な関数しか呼べないので、シグナルハンドラではキューに記録して、メインルーチン内でキューを取り出して処理する形式を考えてみた。

実際に動作させてみると、0.5秒毎にタイマーが起動してキューにシグナル番号が積まれるが、メインルーチンで、0.05秒毎にキューをチェックするので、キューに積まれるシグナル番号は殆ど増える事は無く処理される。

30:30 sigevent:0
30:30 sigevent:0
30:30 sigevent:0
30:30 sigevent:0
30:30 sigevent:0
30:30 sigevent:0
31:31 sigevent:35
31:31 sigevent:0
31:31 sigevent:0
31:31 sigevent:0
31:31 sigevent:0
31:31 sigevent:0
31:31 sigevent:0

実行すると、こんな感じ。

表示しているのは、
キュー先頭(head):キュー末尾(tail) sigevent:シグナル番号
というフォーマットになっている。

しかし、Ctrl-Cを押しっぱなしにすると、メインルーチンでは、usleep()から抜けないので、キューにSIGINTが積まれまくる。

130:130 sigevent:0
131:131 sigevent:35
^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C132:42 sigevent:2
133:42 sigevent:2
134:42 sigevent:2
135:43 sigevent:2
136:43 sigevent:2
137:43 sigevent:2
138:43 sigevent:2
139:43 sigevent:2
140:43 sigevent:2
141:43 sigevent:2
142:43 sigevent:2
143:43 sigevent:2
144:44 sigevent:2
145:44 sigevent:35

ちなみにこのキューはオーバーフローすると、古いデータを捨てるようになっている。オーバフローを確認する方法は作ってない(笑)。

Ctrl-Cを離すと、メインルーチンでキューに溜まっているデータをせっせと処理し、キューの先頭のheadの数字と末尾のtailの数字がみるみる接近していくのが見て取れる。

これで、メインルーチンでシグナル割り込みを検知し、malloc()、printf()使いたい放題。
難点は、ちょっとリアルタイム性が悪くなるという点だな。

このプログラムはリアルタイムライブラリを使うので、コンパイル時には -lrt オプションがいる。

【買い物】フルーツグラノラ

20091018_1

業務用スーパーへ行ったら、フルーツグラノラのデザインが一新されていて、いつものデザインを探して、一瞬、品切れかと思った。

印刷代が安そう 🙂
業務用だから、実利が重要であって、虚飾は必要無いから、実に合理的だな。

棚にあるだけ9個全部購入。一応、店員に、「棚にあるだけしか無いのか?」と尋ねると、棚にあるだけとの返答で、今回は1ケースを注文しておいた。

ブログに書いておかないと、忘れてしまいそうだから、書いておく。

待ってくれないsleep

というC言語のプログラムだと、1秒待ってループってな感じだけど、create_timer()とかでタイマー作ってシグナル割り込みがあると、時間に関わらず、シグナルが発生した時点で、sleep()から抜けるんやな。

メイン処理で、sleep()で1秒間隔、タイマーの割り込みで0.5秒間隔でシグナルが発生するとすると、sleep()は必ず-1の戻り値で抜けてしまい、メイン処理は0.5秒間隔でループするんだな。

シグナルが来たら、メイン処理で何かするって組み方だと、sleep()がシグナルで抜けてくれた方がデッドロックが無くて良さそうだ。

歯の定期メンテナンス

先々週に上側やって、今日は下側の歯石取り。

虫歯も歯周病も細菌が原因で、口内細菌が安定しない幼児期に親から伝染され、一生、虫歯や歯周病の可能性に怯えながら生きていく事になる。

パーフェクトペリオってので治療すれば、歯周病原因菌を撲滅でき、そもそも歯周病にならなくなるから、やってみたい気がするな。

RBIO-2U

社長にRBIO-2Uを買ってもらった。

USBインターフェースだが、Ubuntu 9.04 Desktopのマシンに繋いだら、USB Serialportとしてサックリ認識。

ターミナルで”PCR01″とかコマンド送るとリレーがカチカチ作動する。

使い方は色々あるが、例えば、パソコンの温度が高い時に、外付けの強力な電動ファンのスイッチを自動で入れるとか、炭酸ガスボンベのソレノイドバルブを開閉するとか応用次第で色々楽しそうな事ができそうだ。

リレー出力10、入力4だが、入力ポートが結構おもしろい。GNDと入力の線を短絡させて、RBIOに”FB0″とコマンドを送ると”0″と返ってきて、開放状態だと、”255″という文字列がシリアルから返ってくる。

これも色々と応用が効くが、出力と入力と合わせて、電動ねずみ取り機とか作れるな(笑)

餌のチーズに触れると、入力で検知して、リレー出力で扉をガシャンと電動で閉じるってな具合。果てしなく無用の長物感がするが、まあパソコンで入力の判断と出力ができるってのが色々応用できて、おもちゃとして面白い。

【Apache】穴

会社の自分のマシンは、NIC二枚挿しで、一方をネットワークテスト用のローカルネットが切ってある。

そのローカルネットで、motionを動かしているが、こいつは8081番のポートを、Webブラウザで叩いてやると、カメラ画像がモーションJPEGで見る事ができる。

これは、当然、ローカルネットの外では見る事ができないので、自分のマシンのApacheの特定ディレクトリの.htaccess で

RewriteEngine ON
RewriteRule  (.*)/ http://$1:8081/ [P]

なんてやって、ローカルマシンの motion のモーションJPEGを外部公開する設定にした。

http://localhost/hoge/camera/172.16.0.12/

とやると、外部から参照可能の自分のマシンのApacheが、
http://172.16.0.12:8081/

を実行して、先のURLのコンテンツを置き換えてくれる。

しかし、これって、camera以下のIPアドレス部分を変えれば、どんなホストにもアクセス可能だから、どうみても穴だよなあ…。

ただ、色々と制約があって、
・DNSは使えない
・閲覧するカメラの数は決まっていない。
・motionの動くマシンのネットワークは決定していない。

という理由から、mod_rewriteを使って、URLに任意のIPアドレスをぶら下げるというインターフェースしか思いつかぬ。

PHPで、proxyモドキを作ってみたが、JPEGの画像が書き換わってるのが分かる程、オーバーヘッドがでかいので、動画データの転送には向いてないから断念した。

なんかいい方法ないかなあ。

【PHP】設定ファイル書き出し

PHP でコンフィグレーションファイルを読むのに
parse_ini_file()があるが、書き込む関数が見当たらない。

webで検索しても見つからないので作ってみた。

これで一応、parse_ini_file()のサンプルが正常に展開格納できるが、Zend Frameworkにiniファイル書くヤツがあるというのが分かった。

しかし、Zend Framework の Zend_Config_Writer_Ini() と同じ結果だから、手軽に使うならこれでいいや。