记录一个解决问题的过程,也许有人会碰到相同的问题:
最近做一个分布式的课题,在测试的时候发现当并发度超过某个值的时候connect()函数就会超时。第一直觉是文件描述符的数量超过了某些系统限制,于是上网查各种方法扩大文件描述符上限。但是查来查去像无头苍蝇,改这个改那个问题也一直没解决。过程很痛苦,因为我其实并不在乎这些实现上的细节,我只是想完成算法的测试而已。后来又想:也许不是超过了什么系统限制,而是连接数太高撑破了某些队列。于是又上网查与队列相关的关键词,还是没结果。最后我灵光一现,如果真的是因为队列被撑破,那我也不用非要扩大队列,我放慢填充队列的时间,给消费者足够的时间消耗取走队列里的东西不就行了。于是在创立两次链接之间加了个sleep,再测试,果然没有超时了,问题解决。
// An highlighted block
static void init_connection(int x_fd[])
{
struct epoll_event ev;
for(int i=0; i<NODE_NUM; i++)
{
x_fd[i] = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
int opt = 1;
setsockopt(x_fd[i], SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
int connect_times = 0;
while(connect(x_fd[i], (struct sockaddr*)&server_addr[i], sizeof(struct sockaddr_in)) < 0) {
...
}
ev.events = EPOLLIN;
ev.data.fd = i;
if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, x_fd[i], &ev) == -1) {
...
}
g_usleep(500000); // Too frequent connections will overflow "some" queue and make some connections lost.
}
}
关键就在上面的g_usleep函数。