低cpu-usage方式来监视与localhost的连接

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

似乎无阻塞连接到localhost总是立即失败,然后poll()立即返回,并在revents中设置POLLIN标志。这可以防止CPU进入阻塞状态,并且整个系统在相当高的CPU使用率下运行。

PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
1470 panruoc+  20   0   12956   1956   1820 S  26.2  0.0   2:09.49 zz1

任何建议都是适当的。这是我的测试代码

int main(int argc, char *argv[])
{
    struct sockdesc {
        char *host;
        int port;
        int sockfd;
    };
    struct sockdesc sdes[] = {
        {"localhost", 6000},
        {"111.206.239.212", 6000},
    };
    unsigned int i;

    for(i = 0; i < 2; i++) {
        tcp_connect(sdes[i].host, sdes[i].port, &sdes[i].sockfd);
        printf("sockfd = %d, %d\n", sdes[i].sockfd, errno);
    }

    if(!nonblocking)
        return 0;

    struct pollfd pollfds[2];
    pollfds[0].fd = sdes[0].sockfd;
    pollfds[1].fd = sdes[1].sockfd;
    pollfds[0].events = POLLIN;
    pollfds[1].events = POLLIN;

    int conns;
    for(conns = 0; conns != 3; ) {
        int nfds = poll(pollfds, 2, -1);
        if(nfds <= 0)
            exit(1);
        for(i = 0; (int)i < nfds; i++) {
            if(pollfds[i].revents) {
                if(pollfds[i].revents & POLLIN)
                    conns |= i;
                printf(" fd = %d, revents = 0x%04x\n", sdes[i].sockfd, pollfds[i].revents);
            }
        }
    }
    return 0;
}

BR,Ruochen

sockets cpu-usage connect nonblocking
1个回答
0
投票

你的for-loop看起来很可疑:

for(conns = 0; conns != 3; ) {

conns什么时候变成三个?

看来你的意图如下:

            if(pollfds[i].revents & POLLIN)
                conns |= i;

但如果i是第一个插座的0conns |= i将不会改变该值。

当两个套接字都有可用的数据时,你的poll调用将立即开始返回,但你陷入无限循环。因此,高CPU开销。

看起来你的代码的意图是保持循环,直到两个套接字都有可供读取的数据。然后打破循环。所以我怀疑你真的是这个意思:

                conns |= (i+1);

还有其他问题。 poll返回有效套接字描述符的数量。因此这条线;

for(i = 0; (int)i < nfds; i++) {

因此,如果与pollfds [1]关联的套接字具有可用数据,则nfds将仅为1.因此,您的循环将仅评估pollfds[0]是否具有数据。

让我们清理您的代码:

int ready_set = 0x00;
int all_ready_set = 0x03;
int num_sockets = 2;
while (ready_set != all_ready_set)
{
    int nfds = poll(pollfds, 2, -1);

    if(nfds <= 0)
    {
        // I would not actually exit. If a socket gets closed locally, you would have a valid and expected error, but maybe that can't happen in your program
        exit(1);
    }

    for (i = 0; i < num_sockets; i++)
    {
        if (pollfds[i].revents & POLLIN)
        {
            int mask = 0x01 << i;
            pollfds[i].events = 0; // stop listening for events on this socket
            ready_set |= mask;
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.