c语言 - 使用后如何正确去除信号量?



我正在使用大量信号量来同步对共享内存的多进程访问。

我通过以下方式初始化信号量

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错误来自对集合中的信号量数量使用太大的值。

相关内容

  • 没有找到相关文章

最新更新