低cpu使用率的方法来监视与本地主机的连接

shyt4zoc  于 2023-06-05  发布在  其他
关注(0)|答案(1)|浏览(151)

似乎一个非阻塞连接到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;
}

有没有一种低cpu使用率的方法来监控并修复它?

wz1wpwve

wz1wpwve1#

你的for循环看起来很可疑:

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

conns什么时候会变成3?
看起来你的意图在这里:

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

但是如果第一个socket的i0conns |= 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;
        }
    }
}

相关问题