- 論壇徽章:
- 0
|
ubuntu@ubuntu:~/progs/src/hello$ uname -r
3.16.0-23-generic
ubuntu@ubuntu:~/progs/src/hello$ lsb_release -a
No LSB modules are available.
Distributor ID:Ubuntu
Description:Ubuntu 14.10
Release:14.10
Codename:utopic
ubuntu@ubuntu:~/progs/src/hello$
在以上環(huán)境發(fā)現(xiàn),驚群效應(yīng)并非每次都會(huì)出現(xiàn),內(nèi)核喚配epoll的進(jìn)程應(yīng)該是輪流來喚配的。當(dāng)**第一個(gè)進(jìn)程之后,如果這個(gè)進(jìn)程的處理足夠快,快到把多個(gè)進(jìn)程同時(shí)監(jiān)聽的fd的事件都處理完了。那么其他的進(jìn)程就不會(huì)被**了。
簡單測試代碼
while(true)
{
//printf("%s epoll wait invoked...\r\n", szName);
// 結(jié)論,多個(gè)進(jìn)程同時(shí)epoll時(shí),未必會(huì)引起驚群,猜測epoll有可讀事件時(shí),會(huì)輪著來**線程,
// 同時(shí)每一個(gè)**的線程都會(huì)執(zhí)行epoll_wait,如果前一個(gè)**的線程已經(jīng)把epoll_wait里面的可讀事件都處理完成了
// 那么將不會(huì)再**剩下那些未**的線程。
int ret = epoll_wait(epfd, events, 65535, -1);
// 加入這段sleep代碼之后,所有創(chuàng)建的子進(jìn)程都能在epoll中返回,并執(zhí)行accept,但只有一個(gè)進(jìn)程會(huì)accept成功。
// 其余返回EAGAIN(11)
// sleep(1);
if(ret < 0)
{
char szError[1024+1] = {0};
strerror_r(errno, szError, 1024);
printf("%s epoll_wait error, errno:%d, err:%s\r\n", szName, (int)errno, szError);
}
else if(ret == 0)
{
printf("%s get epoll event size: zero...\r\n", szName);
}
for(int i = 0; i < ret; i++)
{
int sockfd = events[i].data.fd;
if(sockfd == serverfd) //
{
struct sockaddr_in client_addr;
socklen_t client_addrlen = sizeof(client_addr);
int clientfd = accept(serverfd, (struct sockaddr*)&client_addr, &client_addrlen);
printf("%s accept client fd:%d\r\n", szName, clientfd);
}
}
} |
|