0

我正在尝试将 C 中的 System V 信号量用于实验室,但我的课程对我没有帮助。

我可以创建我的信号量并将其删除(使用 semget() 和 semctl()),但我不能与之交互:它的值始终保持不变 (0),并且当我问它时它不会做它的信号量工作到(使用 semop())。

顺便说一句,我在下面提取了我已经写过的关于我的信号量的代码:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

int main()
{
    // some code

    int sem;

    struct sembuf up = {0,1,0};
    struct sembuf down = {0,-1,0};

    sem = semget(IPC_PRIVATE, 1, 777 | IPC_CREAT);
       // Tried with 777 because why not. Originally at 600
       // but it gave me a "Permission denied" error.

    semop(sem, &up, 1); // up

    // some critical code

    semop(sem, &down, 1); // ... and down
    semctl(sem, 0, IPC_RMID); // deletion
}

有人知道我的代码中缺少什么来使我的信号量工作吗?

注意:不,我不能使用 POSIX 信号量。是的,我知道这很可悲。

4

1 回答 1

3

semget()函数返回的不是“信号量”,而是信号量集的 id(或者在您的情况下,是单个信号量,因为您正在创建一组大小为 1 的信号量)。无论信号量本身发生什么变化,该集合 id 都将保持 0 并且不会改变——它不会在您的程序中作为变量保存。

与信号量的交互仅通过semop()andsemctl()函数(也可能是semtimedop(). 例如,如果我们有:

union semun  
{
    int val;
    struct semid_ds *buf;
    ushort array [1];
} sem_attr;
int result;

定义好了,我们可以写:

sem_attr.val = 1;
result = semctl (semaphore_set_index, 0, SETVAL, sem_attr);
if (result == -1) { /* handle error here */ }

它将信号量值设置为 1。


笔记:

  • 我忽略了您对 clang 与另一个编译器的引用。
  • 正如@ThomasJager 建议的那样 -始终检查您的 API 调用返回值是否存在错误。
  • 我将这个答案部分基于这篇文章:

    Linux 中的 System V 信号量

于 2020-02-10T20:37:29.253 回答