シグナルハンドラ

シグナルハンドラ内では、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ケースを注文しておいた。

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