初始化值为0调用sem_open返回EINVAL错误的排查疑问
sem_open返回EINVAL错误的排查
以下是在Linux上运行的一段简单C语言示例代码:
#include <fcntl.h> #include <stdio.h> #include <sys/stat.h> #include <semaphore.h> #define SEM_NAME "/some/sem/name" int main() { sem_t *sem; sem = sem_open(SEM_NAME, O_CREAT, S_IRUSR, 0); if ( sem == SEM_FAILED ) { perror("sem_open"); return 1; } sem_close(sem); sem_unlink(SEM_NAME); return 0; }
运行后输出:
sem_open: Invalid argument
根据手册,EINVAL错误的可能原因如下:
- EINVAL:value大于SEM_VALUE_MAX
- EINVAL:name仅为"/",无其他字符
但示例中value为0,name显然不符合仅为"/"的情况,请问遗漏了什么?
原因分析与解决办法
问题出在有名信号量的名字格式上:Linux实现的POSIX有名信号量要求名字只能包含一个前导斜杠,后续部分不能再出现斜杠(即不能使用多级路径形式的名字)。
你定义的SEM_NAME "/some/sem/name"包含了多个斜杠,违反了sem_open对名字格式的要求,因此触发EINVAL错误。
修改方法很简单,将信号量名字改为单斜杠开头、后续无斜杠的形式即可,比如:
#define SEM_NAME "/some_sem_name"
修改后代码即可正常创建信号量。
内容的提问来源于stack exchange,提问作者Daniel Walker
相关产品推荐
相关产品推荐

