当你往一群鸽子中间扔一块食物,虽然最终只有一个鸽子抢到食物,但所有鸽子都会被惊动来争夺,没有抢到食物的鸽子只好回去继续睡觉, 等待下一块食物到来。这样,每扔一块食物,都会惊动所有的鸽子,即为惊群。
操作系统中的现象:
多线程或多进程中,当它们同时阻塞并等待的某一个资源可用时,所有线程/进程都会惊醒,竞争资源。
最后只有一个线程/进程能获得资源,其他职能重新进入等待状态。
这种现象和性能的浪费就叫做惊群效应。
一句话:
惊群效应就是当一个fd的事件被触发时,所有等待这个fd的线程或进程都被唤醒。
在高并发(多线程/多进程/多连接)中,会产生惊群的情况有:
实际上现在的Linux内核实现中不会出现惊群了,只会有一个进程被唤醒(Linux2.6内核)
在多线程设计中,经常会用到互斥和条件变量的问题。当一个线程解锁并通知其他线程的时候,就会出现惊群的现象。
pthread_mutex_lock/pthread_mutex_unlock:线程互斥锁的加锁及解锁函数。 pthread_cond_wait:线程池中的消费者线程等待线程条件变量被通知; pthread_cond_signal/pthread_cond_broadcast: 生产者线程通知线程池中的某个或一些消费者线程池,接收处理任务; 这里的惊群现象出现在3里,pthread_cond_signal,语义上看,是通知一个线程。 调用此函数后,系统会唤醒在相同条件变量上等待的一个或多个线程(可参看手册)。 如果通知了多个线程,则发生了惊群。
正常的用法
所有线程共用一个锁,共用一个条件变量 当pthread_cond_signal通知时,就可能会出现惊群
解决惊群的方法:
所有线程共用一个锁,每个线程有自已的条件变量 pthread_cond_signal通知时,定向(如hash计算)通知某个线程的条件变量,不会出现惊群
参考:https://blog.csdn.net/second60/article/details/81252106
背景:有个项目出现某用户进程消息处理中占用大量物理内存并在处理结束后未释放
参考以下说明
参考:
Linux glibc 内存站岗问题及解决方法
https://blog.csdn.net/21cnbao/article/details/118004993