似乎到本地主机的无阻塞连接总是立即失败,然后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,若晨
答案 0 :(得分:0)
您的for循环看起来可疑:
for(conns = 0; conns != 3; ) {
conns
什么时候变成三?
您的意图似乎在这里:
if(pollfds[i].revents & POLLIN)
conns |= i;
但是如果第一个套接字的i
是0
,则conns |= 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;
}
}
}