truncate (2)
自作中のビーコンモニタは Linux 上で動いていて、複数のプロセスを協調させて動作しています。最近になって、その中のビーコン自動録音用のプロセスで一日のうちのある時刻において、ALSA サウンドデータ取り込みがオーバーランを起こすことに気付きました。いつも同じ時刻なのです。おまけに、プロセススケジューリングを SCHED_FIFO で動かしているのにですよ!
最初、SoftRock 受信機の周波数切り替えでこけるのでないか*1と考えたり、ファイルの open(), close() で予想以上の時間を要しているのではないか*2と考えていたのですが、朝の通勤電車の中で思いつきました。
そうだ。一日一回、1週間以上前の古い録音データを消す cron が原因だ!*3
実は、一日分の音声データは 15GB に及ぶのですが、これを unlink() するときにカーネルに負荷がかかって、せっかく SCHED_FIFO のプロセスをブロックしてしまっているようです。まだ、想像ですけど。
考えられる解決策は 2つ。
- Linux カーネルのスケジューリングをもう少し勉強して、unlink() が SCHED_FIFO プロセスをブロックしないようにする。(できそうだけど、調べるのメンドーだなあ)
- デカいファイルをいきなり unlink() しないで、少しずつ truncate() してから消す。
後者は Linux に依存しないので、ちょっと美しいような気がしています。惜しむらくは、truncate (2) で実装したユーザーコマンドが標準では存在しないことです。truncate (2) は 4.2BSD で実装されたシステムコールのようで、それだけを呼び出すユーザーコマンドというのは、作られなかったのでしょうか。誰か御存知の方は、教えてくださいまし。