惊群效应和内存站岗问题

惊群效应和内存站岗问题


有一次有人问我什么是惊群效应……

1. 惊群效应

1.1 惊群效应是什么

当你往一群鸽子中间扔一块食物,虽然最终只有一个鸽子抢到食物,但所有鸽子都会被惊动来争夺,没有抢到食物的鸽子只好回去继续睡觉, 等待下一块食物到来。这样,每扔一块食物,都会惊动所有的鸽子,即为惊群。

操作系统中的现象:
多线程或多进程中,当它们同时阻塞并等待的某一个资源可用时,所有线程/进程都会惊醒,竞争资源。
最后只有一个线程/进程能获得资源,其他职能重新进入等待状态。
这种现象和性能的浪费就叫做惊群效应。

一句话:
惊群效应就是当一个fd的事件被触发时,所有等待这个fd的线程或进程都被唤醒。

1.2 惊群效应的问题

  1. 惊醒所有进程/线程,导致n-1个进程/线程做了无效的调度,上下文切换,cpu瞬时增高
  2. 多个进程/线程争抢资源,所以涉及到同步问题,需对资源进行加锁保护,加解锁加大系统CPU开销

1.3 惊群的几种情况

在高并发(多线程/多进程/多连接)中,会产生惊群的情况有:

1.3.1 accept惊群(新版内核已解决)

实际上现在的Linux内核实现中不会出现惊群了,只会有一个进程被唤醒(Linux2.6内核)

1.3.2. epoll惊群

1.3.3. 线程池惊群

在多线程设计中,经常会用到互斥和条件变量的问题。当一个线程解锁并通知其他线程的时候,就会出现惊群的现象。

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

2. 内存站岗问题

背景:有个项目出现某用户进程消息处理中占用大量物理内存并在处理结束后未释放

参考以下说明
参考:
Linux glibc 内存站岗问题及解决方法
https://blog.csdn.net/21cnbao/article/details/118004993

上一篇:linux——线程通信(1)


下一篇:C线程池