c - semctl GETVAL 无法读取信号量值

Posted

技术标签:

【中文标题】c - semctl GETVAL 无法读取信号量值【英文标题】:c - semctl GETVAL can't read the semaphore value 【发布时间】:2016-02-01 16:14:36 【问题描述】:

我正在为我的大学做一个项目,所以我不能使用 semaphore.h 库。

我要做的是将信号量初始化为值 MAX_ACCESS(默认为 10),如果该信号量可用,请执行操作。

semId = semget(SEM_KEY, 1, IPC_CREAT | 0666);
if (semId == -1) errExit("semget 1");
if (initSem(semId, 0, MAX_ACCESS) == -1) errExit("initSem");

initSem() 定义如下:

int initSem(int semId, int semNum, int val) 
    union semun arg;

    arg.val = val;
    return semctl(semId, semNum, SETVAL, arg);

据我所知,它按预期工作。它将信号量值设置为 10。 只是为了发布所有内容,semun 是:

union semun 
int val;
struct semid_ds* buf;
unsigned short* array;
#if defined(_linux_)
    struct seminfo* _buf;
#endif
;

导致我出现问题的是函数 smAvailable()

int semAvailable(int semId, int semNum) 
union semun arg;

if (semctl(semId, semNum, GETVAL, arg) == -1) errExit("semAvailable: semctl");
return (arg.val > 0); 

此函数应该获取信号量的值,如果可用(大于零)则返回。虽然当我使用 semavailable() 作为条件时,在 initSem() 之后,它总是返回 0。

if (semAvailable(semId, 0)) 
/*do things*/

所以我尝试在 semAvailable 中打印 arg.val 的值并打印为零,然后我尝试在 initSem 中打印它,在调用 semctl(semid, 0, GETVAL, arg) 并打印正确的值之后,最后,我尝试在 initSem() 之后立即在主程序中调用 semctl() 并打印 arg.val 的值,并打印初始化变量的值。

if (initSem(semId, 0, MAX_ACCESS) == -1) errExit("initSem");
arg.val = 0;
semctl(semId, 0, GETVAL, arg);
printf("Semctl val: %d\n", arg.val); /*This print 0*/

为什么在 semctl 之后信号量的值没有存储在 arg.val 中?我错过了什么明显的东西吗?

【问题讨论】:

【参考方案1】:

信号量的值是函数semctl使用GETVAL命令的返回值。

int semValue = semctl(semId, 0, GETVAL, arg);
printf("Semctl val: %d\n", semValue);

你不能期望一个没有通过地址(指针)传递参数的函数可以将一个值返回到一个通过值传递的变量中。..

HERE你可以找到semctl函数的所有命令的完整示例。

【讨论】:

以上是关于c - semctl GETVAL 无法读取信号量值的主要内容,如果未能解决你的问题,请参考以下文章

Linux进程间通信 -- 信号量 semget()semop()semctl()

shmctl 和 semctl 不删除 ipc

IPC_RMID 不适用于带有 C++ 的 linux

使用后如何正确删除信号量?

使用IPC_PRIVATE信号量简单的例子

C系统v信号量不锁定关键区域