1. Linux惊群效应
多线程或多进程在同时阻塞等待一个事件而处于休眠态时,如果等待的事件发生,则去唤醒了所有的进程或者线程,但最终只有一个进程或线程可以获取资源,而其他进、线程又重新进入休眠状态,这种现象和浪费性能就叫惊群。
2. 惊群效应浪费的资源
- 无效的context switch,无效的调度造成系统性能降低,造成诸如cache整体失效等
- 为了确保一个进、线程得到资源,用户需要对获取资源操作进行加锁保护,进一步加大了系统开销
3.惊群的解决办法
应该分情况讨论:
- 对于线程池,signal_cond_wait造成的线程休眠,如果现实需求不需要唤醒所有线程,则可以使用noticy_once()来唤醒一个线程。
- 如果是epoll函数调用的惊群问题,则可以参考Nginx的解决方法,在多个进程将listenfd加入到epoll之前,先获取全局互斥锁,获取锁的才可以将listenfd加入到epoll中,当网络连接事件到来时,只有epoll中含有listenfd的线程才会被唤醒。如此来解决epoll调用中的惊群问题。
// demo
epollfd = epoll_create(FDSIZE);
pthread_mutex_lock(&globalLock);
add_event(epollfd,listenfd,EPOLLIN);
pthread_mutex_unlock(&globalLock);
for(;;){
ret = epoll_wait(epollfd,events,EPOLLEVENTS,-1);
handle_events(epolfd,events,ret,listenfd,buf);
}
网友评论