似乎一个非阻塞连接到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使用率的方法来监控并修复它?
1条答案
按热度按时间wz1wpwve1#
你的for循环看起来很可疑:
conns
什么时候会变成3?看起来你的意图在这里:
但是如果第一个socket的
i
是0
,conns |= i
不会改变值。当两个套接字都有数据可用时,
poll
调用将立即开始返回,但您陷入了无限循环。因此,CPU开销很高。看起来您的代码的意图是停留在循环中,直到两个套接字都有数据可读取。那就跳出循环。所以我猜你真的是这个意思:
还有其他问题。
poll
返回有效套接字描述符的数量。因此这条线;因此,如果与pollfds[1]关联的套接字有可用数据,则
nfds
将仅为1。因此,你的循环只会评估pollfds[0]
是否有数据。让我们整理一下你的代码: