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)系统调用来实现它。

顺便说一句,在多线程方法中,您可以让主线程执行事件循环,而其他线程执行其他处理。

于 2012-10-09T09:33:02.790 回答
1

您的 SIGALRM 信号处理程序是什么样的?

一个空的身体很好,但你需要一个真正的处理程序,安装时不带 标志SA_RESTART;否则信号传递不会中断阻塞 I/O 功能。

由于信号可能会在已经有一些数据可用的时候到达(只是不是所有的预期),中断的 I/O 函数可能会返回一个短计数。这可能很难检测到,所以最好让超时中断重复(很快,比如每十毫秒)。当您的代码注意到它已被中断时,您应该明确解除计时器,以停止重复中断。

我个人也会使用一个全局volatile sig_atomic_t keep_running;标志,它在设置超时时设置为非零,并由信号处理程序清除。

于 2012-10-09T10:27:15.913 回答