我已经完成了与定时器相关的不同问题。它接缝我的代码应该工作。但是在接收套接字上的数据时发生超时时它不起作用。我有一个名为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);
}
在超时限制内收到数据时,它可以正常工作。但是当计时器到期时它会卡住。 请帮我搞清楚。
答案 0 :(得分:1)
使用或实施您的事件循环,可能使用libevent或Gtk / Glib或Qt / QCore,也可以使用poll(2)和timerfd_create(2)系统调用来实现。
BTW,在多线程方法中,您可以让主线程执行事件循环,其他线程执行其他处理。答案 1 :(得分:1)
您的SIGALRM信号处理程序是什么样的?
空体很好,但你需要一个真正的处理程序,安装而不用 SA_RESTART
标志;否则信号传递不会中断阻塞I / O功能。
由于信号可能已经到达已经有一些数据可用的点(只是所有预期),因此中断的I / O功能可能会返回一个短计数。这可能很难检测,因此最好重复超时中断(很快,比如每十毫秒)。当您的代码注意到它已被中断时,您应该明确撤防计时器,以停止重复中断。
我个人也会使用全局volatile sig_atomic_t keep_running;
标志,在设置超时时设置为非零,并由信号处理程序清除。