pselect 偶尔会被中断

问题描述 投票:0回答:2

首先也是最重要的是,我没有将其标记为有关“pselect”的问题的声誉,所以我选择了“select”。

我使用 pselect 来处理 UDP 套接字上的超时。代码如下:

UDP_STATUS udp_socket_recv(udp_socket_t* p_sock, int* p_bytes_rcvd)
{
    int res = 0;
    fd_set fds;
    struct timespec timeout;

    FD_ZERO(&fds);
    FD_SET(p_sock->m_socket, &fds);

    if (p_sock->m_timeout == NULL) {
        res = pselect(p_sock->m_socket + 1, &fds, NULL, NULL, NULL, NULL);
    } else {
        timeout.tv_sec = p_sock->m_timeout->tv_sec;
        timeout.tv_msec = p_sock->m_timeout->tv_usec * 1000;
        res = pselect(p_sock->m_socket + 1, &fds, NULL, NULL, &timeout, NULL);
    }

    if (res == 0)
        return UDP_TIMEOUT;
    else if (res == -1) {
        printf("pselect error: %s\n", strerror(errno)); /* Sometimes we end up here */
        return UDP_FAILURE;
    }

    res = recvfrom(p_sock->m_socket, ..); /* etc etc */
}

现在,上述方法在“绝大多数”情况下都可以正常工作(尽管我可能会输错一些内容,因为我无权复制/粘贴)。然而,pselect 有时会返回 -1,并且 strerror(errno) 调用打印“中断的系统调用”。 我什至不确定这就是你想要的套接字超时方式,我什至不记得我是如何想出这个解决方案的......

非常感谢任何帮助。

c sockets udp posix-select
2个回答
2
投票
中断的系统调用

不是错误条件,只是当您的程序在系统调用内被阻塞时发生的事情(信号被传递并且可能被处理)。您可以忽略它并简单地循环,如下所示:(下面的程序不是最佳的,只是演示如何处理 EINTR) UDP_STATUS udp_socket_recv(udp_socket_t* p_sock, int* p_bytes_rcvd) { int res = 0; fd_set fds; struct timespec timeout; FD_ZERO(&fds); FD_SET(p_sock->m_socket, &fds); while(1) { if (p_sock->m_timeout == NULL) { res = pselect(p_sock->m_socket + 1, &fds, NULL, NULL, NULL, NULL); } else { timeout.tv_sec = p_sock->m_timeout->tv_sec; timeout.tv_msec = p_sock->m_timeout->tv_usec * 1000; res = pselect(p_sock->m_socket + 1, &fds, NULL, NULL, &timeout, NULL); } if (res > 0) break; if (res == 0) return UDP_TIMEOUT; switch(errno) { case EINTR: continue; default: printf("pselect error: %s\n", strerror(errno)); /* Sometimes we end up here */ return UDP_FAILURE; } } res = recvfrom(p_sock->m_socket, ..); /* etc etc */ }



0
投票
EINTR

很大程度上是早期 Unix 系统的实现产物,以便它们可以在阻塞系统调用的同时传递信号。关于这是一个聪明还是愚蠢的设计决策已经有很多笔墨了,但这一切的结果是,当调用失败并出现

EINTR
时,进行阻塞系统调用的代码需要重试。
    

© www.soinside.com 2019 - 2024. All rights reserved.