1

私はタイマーに関連して尋ねられたさまざまな質問を経験しました。そして、それは私のコードが機能するはずです。ただし、ソケットでデータを受信して​​いるときにタイムアウトが発生した場合は機能しません。私はtimeout_timerという関数を作成し、その関数の定義を次のようにしています。

timeout_timer(long seconds, long micro_seconds)
{
    struct itimerval *alarm_set;

    if (micro_seconds >= MILLION) {
        seconds = seconds + micro_seconds / MILLION;
        micro_seconds = micro_seconds % MILLION;
    }

    alarm_set = malloc(sizeof (struct itimerval));

    alarm_set->it_value.tv_sec = seconds;
    alarm_set->it_value.tv_usec = micro_seconds;

    alarm_set->it_interval.tv_sec = (seconds == 0 && micro_seconds == 0) ? 0 : 2;
    alarm_set->it_interval.tv_usec = 0;

    if (setitimer(ITIMER_REAL, alarm_set, (struct itimerval *) NULL) == -1) {
        pause();
    }
    free(alarm_set);
}

このtimeout_timer関数を次のように呼び出しました。

timeout_timer(3,0);

memset(rcv_msg,0x0, MAX_MSG); 
if ((n = recv(sd, rcv_msg, MAX_MSG, 0)) <= 0) 
{
    timeout_timer(0,0);
    close(sd);
    break;  
}
else
{
    timeout_timer(0,0);
    trim_space(rcv_msg);
}

タイムアウト制限内でデータを受信した場合は正常に動作します。しかし、タイマーが切れるとき、それは立ち往生しました。私がそれを理解するのを手伝ってください。

4

2 に答える 2

1

おそらくlibeventまたは Gtk/Glib または Qt/QCoreを使用して、イベント ループを使用または実装するか、 poll(2)およびおそらくtimerfd_create(2) syscalls を使用して実装します。

ところで、マルチスレッド アプローチでは、メイン スレッドでイベント ループを実行し、他のスレッドで他の処理を実行することができます。

于 2012-10-09T09:33:02.790 に答える
1

あなたの SIGALRM シグナルハンドラはどのように見えますか?

空の本体は問題ありませんが、フラグなしでインストールされた実際のハンドラーが必要です。SA_RESTARTそれ以外の場合、信号配信はブロッキング I/O 機能を中断しません。

信号は、利用可能なデータがすでに存在するポイントに到着する可能性があるため (すべてが予期されているわけではありません)、中断された I/O 関数は短いカウントを返す場合があります。これは検出が難しい場合があるため、タイムアウト割り込みを繰り返すのが最善です (すぐに、たとえば 10 ミリ秒ごとに)。コードが中断されたことに気付いたら、タイマーを明示的に解除して、繰り返しの中断を停止する必要があります。

volatile sig_atomic_t keep_running;個人的には、タイムアウトを設定するときにゼロ以外に設定され、シグナル ハンドラによってクリアされるグローバル フラグも使用します。

于 2012-10-09T10:27:15.913 に答える