Open nansheng98 opened 1 year ago
请各位大佬不吝赐教!
这个是Server类中的处理定时器的函数,执行这个函数,就意味着这个连接超时了,在定时器事件的处理函数中(cb_fun())已经将该连接关闭了,因此接下来就是要去删除该连接的定时器对象。
感谢答疑! 总结如下
在server类初始化时候:初始化了信号处理函数,并对改进程创建了定时信号。
// 信号处理函数
utils.addsig(SIGPIPE, SIG_IGN); // 这里少个参数?
utils.addsig(SIGALRM, utils.sig_handler, false);
utils.addsig(SIGTERM, utils.sig_handler, false);
alarm(TIMESLOT); // 设置信号SIGALRM 在经过参数seconds 指定的秒数后传送给目前的进程
当定时信号触发后:执行信号处理函数,该函数保证信号的可重入,并通过管道发送信号给主程序。(这里使用了统一事件处理方式)
// 信号处理函数
void Utils::sig_handler(int sig)
{
// 为保证函数的可重入性,保留原来的errno
int save_errno = errno;
int msg = sig;
send(u_pipefd[1], (char *)&msg, 1, 0);
errno = save_errno;
}
主程序中,对信号有信号处理函数:
if ((sockfd == m_pipefd[0]) && (events[i].events & EPOLLIN))
{
// EPOLLIN事件则只有当对端有数据写入时才会触发,
// 所以触发一次后需要不断读取所有数据直到读完EAGAIN为止。
// 否则剩下的数据只有在下次对端有写入时才能一起取出来了。
bool flag = dealwithsignal(timeout, stop_server);
if (false == flag)
LOG_ERROR("%s", "dealclientdata failure");
}
在dealwithsignal函数中:核心是设置如下
timeout = true;
//然后执行如下函数
if (timeout)
{
utils.timer_handler(); // 信号处理函数
LOG_INFO("%s", "timer tick");
timeout = false;
}
信号处理函数中,断开超时连接,然后删除内核事件表,重新打开定时器。
void Utils::timer_handler()
{
// 改进:这里我觉得如果将只删除定时器,改为删除定时器,
// 并且断开连接,内核事件表删除相应事件会更规范
m_timer_lst.tick();
alarm(m_TIMESLOT);
}
问题描述
疑问
在这里仅删除了定时器,客户端连接任然存在,因此代码有些地方需要判断定时器是否存在。如下:
这里只是删掉定时器,没有断开连接。 如果某个任务超时事件到达后,又一次产生读/写事件,怎么办呢? 会触发异常事件吗?
求教
此处是否可以改为删除定时器 并且断开连接,内核事件表删除相应事件呢?