大家都知道,多个accept已经不会出现“惊群”现象了,但是多个epoll还是会出现惊群。
一下服务器程序是多线程的惊群现象。
#include <stdio.h>
#include <sys/types.h>#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <errno.h>
#include <pthread.h>
#include <signal.h>
int sockfd;
int pthread_handle_message(void)
{
struct sockaddr_in cli_addr;
int nfds=0;
int newsockfd=0;
int clilen=0;
struct epoll_event ev;
int fd_epoll=0;
struct epoll_event events[20];
printf(" come in pthread !!\n");
fd_epoll=epoll_create(256);
if(fd_epoll<0)
{
printf("pthread create epoll failed!!!\n");
}
printf("pthread create epoll success!!!\n");
ev.data.fd=sockfd;
ev.events= EPOLLIN | EPOLLET;
epoll_ctl(fd_epoll,EPOLL_CTL_ADD,sockfd,&ev);
printf(" add epoll success!!!\n");
clilen = sizeof(cli_addr);
printf("add epool event!\n");
nfds=epoll_wait(fd_epoll,events,20,-1);
printf("pthread[%d] wake up!\n", pthread_self());
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if(newsockfd==-1 && errno==EAGAIN)
{
printf("no client connect, continue!!!\n");
pthread_exit(NULL);
}
printf(" pthread[%d] accept socket !!\n", pthread_self());
pthread_exit(NULL);
}
static void sig_handler(const int sig) {
printf("Signal handled: %s.\n", strsignal(sig));
exit(0);
}
int main(int argc, char *argv[])
{
int newsockfd;
char buffer[2560000];
struct sockaddr_in serv_addr;
int n;
int flags=0;
int i;
int pid=0;
signal(SIGINT, sig_handler);
signal(SIGTERM, sig_handler);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
printf("opening socket error! \n");
exit(-1);
}
#if 1
flags = fcntl(sockfd, F_GETFL, 0);
fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
#endif
bzero((char *)&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(55560);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
{
printf("socket binding error! \n");
exit(-1);
}
printf("listen socket\n");
listen(sockfd, 5);
pthread_attr_t attr;
pthread_t threadId;
/*初始化属性值,均设为默认值*/
pthread_attr_init(&attr);
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
/* 设置线程为分离属性*/
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
for(i=0; i < 3; i++)
{
if(pthread_create(&threadId,&attr,pthread_handle_message,NULL))
{
perror("pthread_creat error!");
exit(-1);
}
}
while(1)
{
sleep(100);
}
close(sockfd);
}