在管理大型 Linux 服务器环境时,我有时会发现机器达到了其 IPC 限制,更具体地说,是信号量剩余:
Linux #ipcs -u | grep -B2 sema
------ Semaphore Status --------
used arrays = 1024
allocated semaphores = 3072
Linux #ipcs -l | grep -B2 sema
------ Semaphore Limits --------
max number of arrays = 1024
max semaphores per array = 250
max semaphores system wide = 256000
max ops per semop call = 32
semaphore max value = 32767
查看特定的信号量,我只能看到最后访问该信号量的进程:
Linux #ipcs -s -i 63636429
Semaphore Array semid=63636429
uid=11488322 gid=12460 cuid=11488322 cgid=12460
mode=0666, access_perms=0666
nsems = 3
otime = Mon Jul 14 16:02:09 2014
ctime = Mon Jul 14 16:02:05 2014
semnum value ncount zcount pid
0 1 0 0 11551
1 0 0 0 11551
2 0 0 0 11551
所有进程均不再存在。
解决问题并找出信号量未被正确删除的原因的最有效方法是什么?
另一个更普遍的问题是,为什么操作系统不以类似于孤立进程的方式收获未使用的信号量?
答案1
这对我有用,当最后一个进程未运行时删除信号量,但要小心,也许信号量被其他进程使用。
for semid in `ipcs -s | cut -d" " -f 2` ; do pid=`ipcs -s -i $semid | tail -n 2 | head -n 1 | awk '{print $5}'`; running=`ps --no-headers -p $pid | wc -l` ; if [ $running -eq 0 ] ; then ipcrm -s $semid ; fi ; done