Unix Semaphore初始化异常:无法设置初始值的问题求助
解决UNIX信号量初始化的权限与进程问题
咱们一步步拆解你遇到的几个问题,逐个解决:
1. "Permission Denied" 权限错误的根源
你当前的semget调用只传了IPC_CREAT,没有指定权限位参数,这会导致创建的信号量默认权限是0(无任何读写执行权限),所以后续调用semctl设置值时会被系统拒绝,抛出权限错误。
示例里的IPC_CREAT | IPC_EXCL | 0666中,0666是八进制的权限掩码,作用和UNIX文件权限规则一致:给信号量设置所有者、组、其他用户都拥有读写权限(6=读+写权限,0666就是所有人都能读写这个信号量)。
至于你用IPC_CREAT | IPC_EXCL返回-1,是因为这个KEY对应的信号量已经被之前的程序创建过了(IPC资源不会随进程退出自动销毁),IPC_EXCL的作用是:如果指定KEY的信号量已存在,semget就会返回错误,避免重复创建。这种情况是正常的,说明信号量已经存在。
2. 后台进程无法终止的解决方法
后台进程杀不掉,大概率是因为它还持有信号量资源,或者之前的程序残留了未清理的IPC信号量。你可以先手动查看系统中存在的信号量:
ipcs -s
找到KEY为1492的信号量,然后用ipcrm命令删除它:
# 用信号量ID删除 ipcrm -s <semid> # 或者直接用KEY删除 ipcrm -S 1492
删除残留的信号量后,再尝试终止后台进程,应该就能成功了。
3. 修正你的sem_init函数
给semget加上权限位,同时补充必要的错误处理,修正后的代码如下:
#include <iostream> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <stdio.h> #include <errno.h> #include <stdlib.h> #include <string.h> // 包含strerror的头文件 using namespace std; #define KEY (1492) int sem_init(int* semid, unsigned int value) { // 加上0666权限位,确保后续操作有权限 *semid = semget(KEY, 1, IPC_CREAT | 0666); if (*semid == -1) { printf("Unable to obtain semaphore: %s\n", strerror(errno)); return -1; } int ret = semctl( *semid, 0, SETVAL, value); if (ret == -1) { printf("Unable to set semaphore value: %s\n", strerror(errno)); return -1; } return ret; } int main(void) { int* semid = (int*) malloc(sizeof(int)); if (semid == NULL) { // 检查malloc是否成功 printf("Malloc failed.\n"); return 1; } if (sem_init(semid, 1) == -1) { free(semid); return 1; } // 测试完成后建议手动删除信号量,避免残留 // semctl(*semid, 0, IPC_RMID); free(semid); return 0; }
额外提示
- IPC资源(信号量、共享内存、消息队列)不会随进程退出自动销毁,所以测试用程序最好在退出前调用
semctl(*semid, 0, IPC_RMID)删除信号量,避免残留资源干扰后续运行。 - 如果想确保每次都创建全新的信号量,可以保留
IPC_EXCL,但要处理semget返回-1的情况(此时可以选择删除旧信号量再创建,或者直接复用已有的)。 - 权限位可以根据实际需求调整,0666是比较宽松的设置,生产环境可以用更严格的权限(比如0600,只有所有者能访问)。
内容的提问来源于stack exchange,提问作者alexanderd5398
相关产品推荐
相关产品推荐

