No.3ベストアンサー
- 回答日時:
基本的には以下の考え方をとります。
1.selectを行う。
2.timeoutならタイムアウト処理を行い、次のタイムアウト時間は60秒にする。
3.電文受信なら受信処理を行う。但し、次のタイムアウト時間は、前回使ったタイマーの残り時間とする。
問題は、selectが電文受信により終了したとき、タイマーの残り時間をどうやって取得するかです。これに対するシステムコールは提供されていません。従って、以下のようにします。selectの直前で現在の時刻を取得(T1とする)。次にselectの直後で現在の時刻を取得する(T2とする)T2-T1がselectに要した時間となる。従って、前回タイマーの残り時間-(T2-T1)が、次に発行する時のタイマーの時間となります。
前回タイマーの残り時間は、最初又はタイムアウト直後は60秒から開始し、電文受信によるselect終了を継続している間はそれを持ち回ります。
次に、現在時刻の取得ですが、0.001秒のオーダーで必要と言うことですので、gettimeofdayを使用します。これによりマイクロ秒オーダーで現在時刻が取得出来ます。
又、本件とは直接は関係ありませんが、電文受信とタイムアウトの切り分けをFD_ISSETで行っていますが、それは確実に動作していますか。厳密に言えば、以下の手順を踏むべきです。
1.selectの戻り値を取得
2.戻り値=0でタイムアウト
3.戻り値>0電文受信
4.戻り値<0シグナル補足による終了
シグナル補足による終了を考慮する必要がなければ、現行のままでも良いかと思いますが。
コーディングイメージは
FLG=1をタイムアウトとすると
FLG=1
while(1){
ディスクリプタの設定
if (FLG==1){
timeoutへ60秒をセット
}else{
timeout-(T2ーT1)
}
T1を取得(gettimeofday)
select(上記で求めたtimeoutを使用)
T2を取得(gettimeofday)
if (電文受信によるselect完了){
FLG=0
受信処理
}else{
FLG=1
インタバル処理
}
}
時間の引き算は秒とマイクロ秒がありますので、それなりの計算が必要です。たぶんbunarinさんなら判ると思いますのでこれは省略します。
不明点があれば、再度質問して下さい。
No.4
- 回答日時:
#3です。
前回の回答に以下の点を追記します。
1.select(...&timeout.tp )でtimeout.tp の内容が破壊されることがあります。従って
if (FLG==1){
残タイマー=60(残タイマーはtimeoutと同じ型)
}else{
残タイマー=残タイマー-(T2-T1)
}
timeout = 残タイマー
としてtimeout をselectの引数とするようにしてください。
2.残タイマーを計算したとき、残タイマーが負になることがあるかもしれませんので、残タイマーが負の場合は
残タイマーに0をセットする部分を追加しておいてください。
3.受信処理に要する時間は考慮していません。その時間まで考慮する必要があるなら、T2は受信処理完了後の時間としてください。
>問題は、selectが電文受信により終了したとき、
>タイマーの残り時間をどうやって取得するかです。
>これに対するシステムコールは提供されていません。
そうですか、selectを呼んでしまうとやはり、前回の
timeoutの設定がなくなってしまうのは、
自前で対処するしかないんですね。
配慮の行き届いた回答をしていただき
大変参考になりました。
ありがとうございました。
No.2
- 回答日時:
行いたいことは、以下の事でよいでしょうか。
1.一定間隔(60秒)でインターバル処理を実行したい。
2.但し、その間にデータを受信した場合は、受信処理を行いたい。
3.受信処理を行った後は、受信処理後、60秒後にインタバル処理が実行されるのではなく、以前に発行したタイマーを含めて、そこから60秒後に、インタバル処理を行いたい。(要は受信処理に関係なくインタバル処理は60秒間隔で行いたい)
4.上記に対して全てyesと言う前提として、タイマーの精度は秒程度のオーダーで良いでしょうか。(つまり59~61秒程度の揺らぎはOKですか。)それとも、更に細かい精度で、60秒に1回起動されることを要求されますか?
No.1
- 回答日時:
インターバル処理とはなんのことでしょうか?
>インターバルでは跳ねなくなってしまいます。
具体的にはどういうことでしょうか?
>インターバルの引数をNULLにする
インターバル処理の引数はどのようになっていますか?
また、どのような機能をもっていますか?
この回答への補足
>インターバル処理とはなんのことでしょうか?
一定間隔で処理をするためのselectの単にタイムアウトの設定のことです。
timeout.tv_sec = 60;
timeout.tv_usec = 0;
ret = select(0,NULL,NULL,NULL,&timeout);
>>インターバルでは跳ねなくなってしまいます。
>具体的にはどういうことでしょうか?
while( 1 ){
FD_ZERO( &readfds );
FD_SET( channel, &readfds );
timeout.tp.tv_sec = 60;
timeout.tp.tv_usec = 0;
/* select によりイベント待ち */
status = select( FD_SETSIZE, &readfds, NULL, NULL, &timeout.tp );
if( FD_ISSET( channel, &readfds ) ){
// 受信処理
} else {
// インターバル処理
}
}
こう書くとインターバル処理のときだけでなく
受信処理の時もタイマーが再設定されてしまいますが、
本来やりたいのはインターバル処理の時だけselectにタイマーを設定したいので
int FLG=1;
while( 1 ){
FD_ZERO( &readfds );
FD_SET( channel, &readfds );
timeout.tp.tv_sec = 60;
timeout.tp.tv_usec = 0;
/* select によりイベント待ち */
if( FLG==1 ){
select( FD_SETSIZE, &readfds, NULL, NULL, &timeout.tp );
} else{
select( FD_SETSIZE, &readfds, NULL, NULL, NULL );
}
if( FD_ISSET( channel, &readfds ) ){
// 受信処理
FLG=0;
} else {
// インターバル処理
FLG=1
}
}
と書くと今度は受信処理を一度行うと
タイムアウトが利かなくなってしまいます。
そこで受信処理後のselectを実行するときに
直前で設定したタイムアウトの設定を消すことなく
実行するにはどうすればよろしいでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) excelVBAについて。 4 2022/11/21 16:15
- Visual Basic(VBA) excelVBAについて。 1 2022/11/30 06:16
- Visual Basic(VBA) データのある範囲を選択するVBAについて 2 2022/09/03 00:20
- Excel(エクセル) 表示形式、文字列セル(列)に数式を入力するには マクロ 1 2022/09/18 10:53
- Excel(エクセル) ②Excel 簡単にシートコピーしたら前日の残高と日付を変更させたい→マクロの記録でエラーが出ます 8 2022/07/16 20:40
- Excel(エクセル) excelVBAについて。 8 2022/12/11 13:47
- JavaScript 以前の質問だと、どの条件でも配列が表示されてしまいます。 1 2022/07/09 11:40
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- 生物学 おじぎそうの開花 1 2022/09/17 15:10
- Excel(エクセル) ExcelVBAについて。 2 2022/12/10 20:08
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
【C#/Java?】try-catchでcatch...
-
IF文に時間(何時から何時ま...
-
フォルダのアクセス権確認について
-
private subモジュールを他のモ...
-
マクロで、次のコードへ行く前...
-
Word VBA。各マクロの間に待ち...
-
シェルスクリプトでファイル内...
-
特定のファイルを他のプロセス...
-
【VBA】エラー処理で別プロシー...
-
シグナル 6(SIGABRT)とは?
-
Excel VBA セルの名前があるか...
-
For ~ Next文
-
途中で処理を中断させたい (ア...
-
ドリブン??
-
【C#】Page_Loadさせない方法に...
-
ExcelのVBAで、選択したファイ...
-
Functionで戻り値を複数返す方法
-
特定の名前のオートシェイプの...
-
VB6で定時刻処理
-
VBとSQLServerのセッションが切...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
【C#/Java?】try-catchでcatch...
-
IF文に時間(何時から何時ま...
-
private subモジュールを他のモ...
-
シグナル 6(SIGABRT)とは?
-
Functionで戻り値を複数返す方法
-
特定の名前のオートシェイプの...
-
ExcelのVBAで、選択したファイ...
-
マクロで、次のコードへ行く前...
-
どう増強すべきか
-
VBA 複数の行を高速で削除する...
-
Excel VBA セルの名前があるか...
-
特定のファイルを他のプロセス...
-
Word VBA。各マクロの間に待ち...
-
どうやってもFor文を抜けてしま...
-
【VBA】エラー処理で別プロシー...
-
エクセル VBAで複数セル選択時...
-
シェルスクリプトでファイル内...
-
【Vb.net】プリンタジョブの取得
-
vbaのエラー対応(実行時エラー...
-
VBAでBook読み込み時の非表示方...
おすすめ情報