4

タイムアウトを使用するなど、fwrite がブロックされないようにする方法はありますか?

シナリオは次のとおりです。ネットワーク上で fwrite 呼び出しを行う必要があります (コードの大部分を再利用しているため、それに固執する必要があります)。ただし、ネットワーク ケーブルを引き抜くと、fwrite がブロックされます。回避策はありますか? ヘルプ/提案は大歓迎です。

4

3 に答える 3

5

基になるファイル記述子をノンブロッキング モードに切り替えます。

int fd = fdnum(stream);
int f = fcntl(fd, F_GETFL, 0);
f |= O_NONBLOCK;
fcntl(fd, F_SETFL, f);

この後、ファイル記述子に書き込む準備ができていない場合、 への呼び出しfwrite()はすぐに戻り、EAGAIN に設定されます。errnoループで呼び出してスリープを使用すると、必要なタイムアウト動作を簡単に実装できます。

于 2012-05-19T20:49:40.800 に答える
4

これは@Alexander Bakulinの提案と同じ効果があるはずですが、やや短くなっています。

int fd = fdnum(stream);
int ioctl( fd, FIONBIO, 1 );

参照: http://oss.org.cn/ossdocs/gnu/linux/syscalls_17.html

于 2012-05-19T21:27:37.033 に答える
2

シグナルハンドラーを設定し、alarm()システムコールを使用してそのシグナルの配信をスケジュールすると、fwrite()コールが中断されます。一般的な使用法は次のようになります。

signal(SIGALRM, handle_sigalrm);
received_alarm = 0;
alarm(10);
...some blocking operation...
alarm(0); // cancel the alarm.
if (received_alarm) {
  // command timed out
} else {
  // command completed successfully
}

これは、が呼び出されたときにグローバル変数handle_sigalrm()を設定する関数であることを前提としています。Googleにはいくつかの例があります。received_alarm

これは絶対にこれを処理するための最良の方法ではありませんが、を使用することを余儀なくされている場合は、これが唯一の選択肢である可能性がありますfwrite()。より良い解決策は、select()orpoll()ループと非ブロッキングソケットを使用することですが、コードの大幅な再設計が必要になる場合があります。

于 2012-05-19T20:39:31.347 に答える