(1)查看所有信号 ipcs -s ------ Semaphore Arrays -------- key semid owner perms nsems 0x00008708 0 root 666 1 0x000086f8 217120769 root 666 1 0x0000870a 65538 root 666 1 0x00008707 98307 root 666 1 0x00008709 131076 root 666 1 0x00008706 163845 root 666 1 0x0000870b 196614 root 666 1 (2)查看指定信号信息 -i # ipcs -s -i 249823287 Semaphore Array semid=249823287 uid=0 gid=0 cuid=0 cgid=0 mode=0666, access_perms=0666 nsems = 1 otime = Not set ctime = Thu Aug 15 14:25:08 2013 semnum value ncount zcount pid 0 0 1 0 0 # sysctl -a|grep sem kernel.sem = 250 1024000 32 4096 查看当前信号量系统限制 # ipcs -ls ------ Semaphore Limits -------- max number of arrays = 4096 <------ 系统允许的 【信号集数组】 最大个数 max semaphores per array = 250 <------ 允许每个信号集数组管理多少个信号量, 信号数组包含多个信号 max semaphores system wide = 1024000 <----- 系统创建【信号量】最大数, 该值等于 (max number of arrays) * (max semaphores per array) max ops per semop call = 32 <------- 每次semop操作的时候设置sem_op最大值 semaphore max value = 32767 <------- 信号量最大值 可以通过下面命令临时修改: echo "5010 641280 5010 128" > /proc/sys/kernel/sem (3)测试 测试1 (没有设置SEM_UNDO) 测试程序如下: int main(int argc, char * argv[]) { int nRet = 0; int sem_id = 0; Semaphore sem; nRet = sem.create(0x112233, sem_id); if(nRet) { nRet = sem.open(0x112233, sem_id); } sem.acquire(); //sops[0].sem_flg = 0,没有指定 SEM_UNDO while(true) { sleep(5); } return nRet; } 程序执行完信号量代码后查看信号量信息, value=0, 正常 root@PLATDEV:~# ipcs -s -i 249921584 Semaphore Array semid=249921584 uid=0 gid=0 cuid=0 cgid=0 mode=0666, access_perms=0666 nsems = 1 otime = Thu Aug 15 14:50:26 2013 ctime = Thu Aug 15 14:40:18 2013 semnum value ncount zcount pid 0 0 0 0 858 kill 这个测试程序,再查看信号量信息, value依然等于0, 信号量没资源可用了!下次启动程序就被挂死! root@PLATDEV:~# ipcs -s -i 249921584 Semaphore Array semid=249921584 uid=0 gid=0 cuid=0 cgid=0 mode=0666, access_perms=0666 nsems = 1 otime = Thu Aug 15 14:50:26 2013 ctime = Thu Aug 15 14:40:18 2013 semnum value ncount zcount pid 0 0 1 0 858 我们重新启动进程在获取信号的时候, 由于信号没有资源进程挂死了。 测试2 (信号acquire不设置SEM_UNDO, release设置SEM_UNDO) 测试程序如下: int main(int argc, char * argv[]) { int nRet = 0; int sem_id = 0; Semaphore sem; nRet = sem.create(0x112233, sem_id); if(nRet) { nRet = sem.open(0x112233, sem_id); } sem.acquire(); //sops[0].sem_flg = 0 sem.release(); //sops[0].sem_flg = SEM_UNDO <---- 释放的时候设置 SEM_UNDO while(true) { sleep(5); } return nRet; } 程序执行完信号量代码后查看信号量信息, value=1, 正常 # ipcs -s -i 275021825 Semaphore Array semid=275021825 uid=0 gid=0 cuid=0 cgid=0 mode=0666, access_perms=0666 nsems = 1 otime = Wed Sep 4 17:19:48 2013 ctime = Wed Sep 4 17:19:48 2013 semnum value ncount zcount pid 0 1 0 0 31186 kill 这个测试程序,再查看信号量信息, value=0, 信号量没资源可用了!下次启动程序就被挂死! # ipcs -s -i 275021825 Semaphore Array semid=275021825 uid=0 gid=0 cuid=0 cgid=0 mode=0666, access_perms=0666 nsems = 1 otime = Wed Sep 4 17:26:20 2013 ctime = Wed Sep 4 17:19:48 2013 semnum value ncount zcount pid 0 0 0 0 31186 测试3 (信号acquire设置SEM_UNDO, release不设置SEM_UNDO) 测试程序如下: int main(int argc, char * argv[]) { int nRet = 0; int sem_id = 0; Semaphore sem; nRet = sem.create(0x112233, sem_id); if(nRet) { nRet = sem.open(0x112233, sem_id); } sem.acquire(); //sops[0].sem_flg = SEM_UNDO sem.release(); //sops[0].sem_flg = 0 while(true) { sleep(5); } return nRet; } 程序执行完信号量代码后查看信号量信息, value=1, 正常 # ipcs -s -i 275185665 Semaphore Array semid=275185665 uid=0 gid=0 cuid=0 cgid=0 mode=0666, access_perms=0666 nsems = 1 otime = Thu Sep 5 09:08:10 2013 ctime = Thu Sep 5 09:08:10 2013 semnum value ncount zcount pid 0 1 0 0 28548 kill 这个测试程序,再查看信号量信息, value=2, 信号量已经不正常了 # ipcs -s -i 275185665 Semaphore Array semid=275185665 uid=0 gid=0 cuid=0 cgid=0 mode=0666, access_perms=0666 nsems = 1 otime = Thu Sep 5 09:08:46 2013 ctime = Thu Sep 5 09:08:10 2013 semnum value ncount zcount pid 0 2 0 0 28548 测试4 (信号acquire设置SEM_UNDO, release没设置SEM_UNDO) 测试程序如下: int main(int argc, char * argv[]) { int nRet = 0; int sem_id = 0; Semaphore sem; nRet = sem.create(0x112233, sem_id); if(nRet) { nRet = sem.open(0x112233, sem_id); } for(int i=0; i<32768; i++) { sem.acquire(); //sops[0].sem_flg = SEM_UNDO sem.release(); //sops[0].sem_flg = 0 } while(true) { sleep(5); } return nRet; } 执行到最后一次的时候会报错:(sem最大值32767) semop(semid:280494082) acquire failed. errno:34, errmsg:Numerical result out of range semop(semid:280494082) release success. 程序执行完信号量代码后查看信号量信息, value=2, 已经不正常 # ipcs -s -i 280690690 Semaphore Array semid=280690690 uid=0 gid=0 cuid=0 cgid=0 mode=0666, access_perms=0666 nsems = 1 otime = Thu Sep 5 15:57:10 2013 ctime = Thu Sep 5 15:57:07 2013 semnum value ncount zcount pid 0 2 0 0 26913 kill 这个测试程序,再查看信号量信息 # ipcs -s -i 280690690 Semaphore Array semid=280690690 uid=0 gid=0 cuid=0 cgid=0 mode=0666, access_perms=0666 nsems = 1 otime = Thu Sep 5 15:58:46 2013 ctime = Thu Sep 5 15:57:07 2013 semnum value ncount zcount pid 0 32767 0 0 26913 测试5 (信号acquire设置SEM_UNDO, release设置SEM_UNDO) 测试程序如下: int main(int argc, char * argv[]) { int nRet = 0; int sem_id = 0; Semaphore sem; nRet = sem.create(0x112233, sem_id); if(nRet) { nRet = sem.open(0x112233, sem_id); } sem.acquire(); //sops[0].sem_flg = SEM_UNDO sem.release(); //sops[0].sem_flg = SEM_UNDO while(true) { sleep(5); } return nRet; } 程序执行完信号量代码后查看信号量信息, value=1, 正常 # ipcs -s -i 275218433 Semaphore Array semid=275218433 uid=0 gid=0 cuid=0 cgid=0 mode=0666, access_perms=0666 nsems = 1 otime = Thu Sep 5 09:11:28 2013 ctime = Thu Sep 5 09:11:28 2013 semnum value ncount zcount pid 0 1 0 0 28706 kill 这个测试程序,再查看信号量信息, value=1,依然正常 # ipcs -s -i 275218433 Semaphore Array semid=275218433 uid=0 gid=0 cuid=0 cgid=0 mode=0666, access_perms=0666 nsems = 1 otime = Thu Sep 5 09:13:53 2013 ctime = Thu Sep 5 09:11:28 2013 semnum value ncount zcount pid 0 1 0 0 28706 测试6 (信号acquire设置SEM_UNDO, release设置SEM_UNDO, 在两者之间程序退出) 测试程序如下: int main(int argc, char * argv[]) { int nRet = 0; int sem_id = 0; Semaphore sem; nRet = sem.create(0x112233, sem_id); if(nRet) { nRet = sem.open(0x112233, sem_id); } sem.acquire(); //sops[0].sem_flg = SEM_UNDO exit(-1); //程序退出, 这个测试类似测试3, 但系统处理机制不同 sem.release(); //sops[0].sem_flg = SEM_UNDO while(true) { sleep(5); } return nRet; } 查看信号量信息, value=1,依然正常, 不同于测试3 # ipcs -s -i 275251201 Semaphore Array semid=275251201 uid=0 gid=0 cuid=0 cgid=0 mode=0666, access_perms=0666 nsems = 1 otime = Thu Sep 5 09:27:50 2013 ctime = Thu Sep 5 09:27:50 2013 semnum value ncount zcount pid 0 1 0 0 29914 【总结】: (1)SEM_UNDO 在进程异常退出信号没有释放资源场景很重要! (2)SEM_UNDO 一定要成对使用