为啥 semget() 在 *创建* 信号量时会导致 EACCES 错误?
Posted
技术标签:
【中文标题】为啥 semget() 在 *创建* 信号量时会导致 EACCES 错误?【英文标题】:Why does semget() cause an EACCES error when *creating* a semaphore?为什么 semget() 在 *创建* 信号量时会导致 EACCES 错误? 【发布时间】:2011-11-13 04:37:50 【问题描述】:我必须为 C++ 项目创建一个信号量数组。我不是从main()
打电话给semget()
;我有一个单独的方法让它更容易,尽管main.cpp
中有一个方法。当我的程序到达 semget(semkey,nsems,0666|IPC_CREAT)
时,它返回 -1 并带有 EACCES errno,这显然意味着“key
存在信号量标识符,但不会授予 semflg
的低 9 位指定的操作权限。”
我已经用 GDB 反复检查了我的代码。 semget()
的所有三个参数看起来都正确,这是程序调用 semget()
的第一个点,因此信号量不存在;我什至跑了ipcs -s
来确定。我在main.cpp
的顶部有#include <sys/sem.h>
。
这里发生了什么?我已经创建并附加了一个共享内存段,这可能与它有关吗?我看不出来。
【问题讨论】:
重启后第一次能正常工作吗? 我没试过。那会影响吗?为什么? 好吧,用ipcs
清理应该可以解决问题,但可以肯定的是,重新启动系统肯定会清理任何剩余的共享资源(信号量、共享内存等...)
...嗯。那成功了。谢谢!
【参考方案1】:
来自手册:
EACCES A semaphore set exists for key, but the calling process does not have permission to
access the set, and does not have the CAP_IPC_OWNER capability.
提醒一下,由于信号量是系统对象,因此只有在为此显式发出系统调用时才会将其删除。 (semctl
与 IPC_RMID
或 ipcrm
术语命令)。
此外,semkey
必须是唯一的(例如从ftok()
函数中检索),或者在您第一次调用semget
之前,可能有另一个程序创建了它。因为它会存在,你会捕获所谓的EACCES
错误,因为并非所有程序都像你一样使用信号量的 0666 权限。
重启会刷新共享对象池(信号量、共享内存段、消息队列):
#!/bin/bash
for i in `ipcs -s | cut -f 2 -d ' '`
do
ipcrm -s $i
done
for i in `ipcs -m | cut -f 2 -d ' '`
do
ipcrm -m $i
done
for i in `ipcs -q | cut -f 2 -d ' '`
do
ipcrm -q $i
done
【讨论】:
以上是关于为啥 semget() 在 *创建* 信号量时会导致 EACCES 错误?的主要内容,如果未能解决你的问题,请参考以下文章
Linux进程间通信 -- 信号量 semget()semop()semctl()