linux的程序通过调用下面函数申请一块共享内存:
int shmget(key_t key, size_t size, int shmflg);
调用此函数,如果能正常申请到共享内存,返回一个共享内存块的shmid。如果失败,返回-1;
因业务需求变更,需要修改程序把size调大。修改后的程序,在调试过程中,有时候shmget()能正常申请到内存,有时候返回-1。而运行旧版本程序,每次都能成功申请到共享内存。
系统里运行命令sysctl -a | grep shm,查看系统限制的共享内存最大值,size未超过最大值。
最终找到故障原因:
因为在同一台linux电脑上反复运行新老程序做对比,老程序ctrl+c强制退出后有时不能正常删除申请到的共享内存。老程序之所以能反复正常运行,是因为每次申请的共享内存key都一样,size都一样,调用shmget()函数,系统判断不存在key标识的共享内存则会新创建,存在则返回已有共享内存,不会报错。
新程序和老程序的key一样,但新程序的size比老程序的size大。新程序调用shmget()函数,系统判断不存在key标识的共享内存则会新创建,此种情况新程序启动正常。如果系统存在key标识的共享内存,因为size比老程序大,所以shmget()函数会返回-1,此种情况新程序启动失败。
解决方案:
1、打印shmget()函数返回的shmid。
2、linux运行命令查看系统里存在的共享内存:
$ ipcs
------------ 共享内存段 --------------
键 shmid 拥有者 权限 字节 连接数 状态
0x65010002 65539 root 666 512000 0
0x00000000 4 root 600 16384 1 目标
3、linux里手动删除老程序退出时未能正常删除的shmid所指的共享内存:
$ ipcrm -m 65539