- ベストアンサー
Linuxでの10msスリープ
Linux初心者です。よろしくお願いします。 Cで記述された旧式のRTOSでのプログラム をLinux環境に移植しようとしていて、 Timesys Linuxを購入予定ですがまだ入手で きてないので、Vine Linux 2.6で試運転させて います。 10ms毎の周期起床するタスクを旧記述では カーネルコールのsleep()で起床待ちさせて 起床タイミングはカーネルのスケジューラに 任せていたため、同じように動かそうとタスク をPosixThreadにしてその上でusleep(), nanosleep()等を実行してみたのですが、 待機時間が2ms以下か、20m以上になってしま って上手くスリープしてくれません。 (スケジューリング周期は10msです。) 標準のLinuxで10ms(毎のスケジューリング タイミングまで)待たせる場合はどういう 方法をとるとよいでしょうか?
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
select関数ではどうでしょうか。 本来は、ソケットを監視する関数ですが 1ms単位でタイムアウト値を設定できます。
その他の回答 (2)
- terra5
- ベストアンサー率34% (574/1662)
>スケジューリング間隔が10msであれば、毎回起床できそうな気がするのです 時間保証は無いでしょうから、毎回起床してもその時間間隔がどの程度正確かは状況次第です。 他に優先度の高い時間のかかる処理が合計10ms以上動くことも十分ありえますよね。 どの程度の精度で実行されるかは、OSとその設定やドライバのつくり、他に動いているプロセス、タスク、スレッドの処理内容やプライオリティによると思います。 逆にRTOSならプライオリティや割り込み意識して組んでいれば、sleep()相当の処理でもそれなりの精度がでますが。(sleepだと自身の処理時間が反映されないのでその分不正確) 通常のOSのユーザープロセスでの高精度の時間処理は無理と考えた方がいいと思いますが。 まあ、カーネルレベルでもそう簡単にはRTOSレベルにはいかないでしょうが。 仕事でWindowsで60Hzの処理をやることがありますが、開発途中までは時間精度は無視です。 ターゲットでは外部タイマーから割り込みかけて正確な時間間隔を得ています。
お礼
ありがとうございます。 FIFOで動く部分については、全ての処理の最大負荷 を実測して間に合うように設計しています。 確かに標準カーネルではタイミング精度はあまりよくな いようですね。 タイミング精度はなくても周期性が確保できるようなら 十分なソフトの場合に採用しようかと考えています。
- terra5
- ベストアンサー率34% (574/1662)
RTOSでないLinuxに無理な要求してませんか(^^; ソース上は10msに書けても、まずその精度では動かないと思います。 http://www.mech.tohoku-gakuin.ac.jp/rde/contents/linux/control/lcycle.html そもそも、スケジューリングが10ms単位ぐらいのようですね。 また、プライオリティ等はどうしてますか? 通常ラウンドロビンしてると思いますので, それなりの高いプライオリティにしないと精度以前の問題になりますが。 もし、そういう話がわからないのであれば、リアルタイム制御について、もう少し調べてから取り組んだ方がいいと思います。 私はLinux系でのリアルタイムは経験ないですが、pSOS+とvxWorksは使ったことがあります。
お礼
回答、資料ありがとうございます。 スレッド優先度はpthread_setschedparam() でセットしています。 (もちろんポリシはSCHED_FIFOです) スケジューリング周期を5msにしてみた例を検索 で見つけて読みました。 Timesysであればsleep()のような遅延起床でなく 周期起床の予約関数が用意されてますし、起床タ イミングの精度が必要なので、今回のソフトは標 準カーネルの使用をあきらめていますが、今後他 のソフトの移植を予定してますので、できそうな ら標準カーネルでの動かし方を知っておきたいと 思って質問させていただきました。 スケジューリング間隔が10msであれば、毎回起床 できそうな気がするのですが、仕様的にsleep() では無理なのでしょうか。
お礼
回答ありがとうございます。 その関数は知りませんでした^^; JMを読んで試してみましたところ、うまく スリープすることができました。 タイムアウト設定を1usに設定しても起床 タイミングは経過後の次のスケジューラ処理 時になる遅延起床処理のようです。