質問: やりたいことは一定の無通信時間に対する処理なのですが、もう少し一般的な形で表現して ●あるイベントが一定時間発生しなかったときに特定のイベントを発火させたい というとき、どのような書き方がスマートですか? ごく簡単には、「あるイベント」を受け取るたびに「最終時刻」を記録しておいて1秒ごとのタイマで最終時刻と現在時刻を比較すればいいですし、まあこれでソフトウェア要件は十分満たすことが大半だと思いますが、もう少し厳密に「最後のイベント発生からきっかり○○秒後」にイベントを発火させる書き方、イディオムのようなものがあればご教示いただけませんでしょうか。
回答: こんにちは。 ウォッチドッグ・タイマなどで良く使われますが、実装に用いるハードウェアやOSのリソースにより、その実装方法や注意点は様々ですので、あまり定型的なパターンはないように思います。 ポイントは1タイムアップした時の処理を実行する仕組みと2タイムアップとタイマリスタートがほぼ同時に発生した時にどのようにして制御するのかの2点と思います。 1が決まらないと2を検討できないのでご提示の条件だけでは、処理方針を決めることはできないです。 1を行うために定期的にポーリングする方法は、データ競合の心配がなくプログラムが単純ですので、応答が遅くて良い場合に用いています。 WindowsのSetTimer()APIのようにコールバックが同じスレッドで呼ばれるような場合は、やはりデータ競合の心配はないので比較的楽にかけますが、他の処理にかまけていると応答が遅れ、タイムアップとタイマリスタートのイベントが「同時」に処理待ちになる問題を回避できません。要件によってはどちらが先か記録する仕組みが必要になるかも知れません。 1としてコールバック関数が別スレッドで呼ばれる場合はデータ競合の心配が出てくるので注意深い設計が必要ですが、応答性能を確保できます。 どの方法も一長一短で、要件に応じて適切な方法を選択するしかないと思います。 ちなみにウォッチドッグ・タイマの場合は、一般にタイムアップでシステム・リセットで、1をハードウェアにて実装する場合が多いです。(そもそもソフトウェアの暴走対策なのでソフトウェアで実装すると効果をほとんど期待できない。)