我正在使用大量信号量来同步对共享内存的多进程访问。
我通过以下方式初始化信号量
int scount = 80000;
int semid = semget(IPC_PRIVATE, scount, 0666 | IPC_CREAT);
这工作正常。
在程序结束时,我通过以下方式删除了信号灯集
semctl(semid, 0, IPC_RMID);
但是,当我通过以下方式检查系统中的信号量数量时
ipcs -S
在控制台中,我看到它们仍然存在。
seminfo:
semmap: 30 (# of entries in semaphore map)
semmni: 8 (# of semaphore identifiers)
semmns: 80064 (# of semaphores in system) <------ ????
semmnu: 0 (# of undo structures in system)
semmsl: 87381 (max # of semaphores per id)
semopm: 5 (max # of operations per semop call)
semume: 10 (max # of undo entries per process)
semusz: 32 (size in bytes of undo structure)
semvmx: 32767 (semaphore maximum value)
semaem: 16384 (adjust on exit max value)
我还尝试通过以下方式在控制台中手动删除它们
ipcrm -s [semid]
这似乎删除了设置罚款(即semid
在命令之前和之后列在ipcs -s
中)。然而ipcs -S
仍然显示
semmns: 80064 (# of semaphores in system)
如何在使用后正确清理信号量,使它们不再显示在"semmns: .... (# of semaphores in system)"
中?
我问的原因是,如果没有正确清理信号量,我的下一次程序运行将无法工作,因为打开的信号量数量将超过限制。我需要重新启动以将其重置为 0。
PS:我在Mac OS上,但也希望它在Linux上运行。
semget
不会返回错误。当我通过以下方式初始化信号灯集时,在下一步中会发生错误:
semun_t semun = {.val = 1}; // initial semaphore value => 1 = released
for (int i=0; i<scount; i++){
if(semctl(semid, i, SETVAL, semun) == -1) {perror("semctl init");exit(1);}
}
我得到的错误是:
semctl init: Invalid argument
对于那些遇到相同问题的人:
ipcs -S
调用时semmns
下显示的数字是到目前为止已使用的信号量数。这并不意味着它们仍在使用中。因此,即使您正确删除了信号灯,计数器semmns
也不会降低。
semctl init: Invalid argument
错误来自对集合中的信号量数量使用太大的值。