【问题标题】:Locking semaphores in C problem sys/sem在 C 问题 sys/sem 中锁定信号量
【发布时间】:2010-04-29 16:32:26
【问题描述】:

编辑:这种代码的和平非常好(所以把它作为信号量的例子;)。我的程序中的错误在另一个地方 - 由我的朋友发现。

我的功能有问题。有时两个进程进入临界区。在我花了 10 个小时调试之后,我找不到问题所在。我应该瞄准什么?这段代码有没有可能萌芽?

    // lock semaphore
    static int P(int sem_id)
    {
        struct sembuf sem_b;
        sem_b.sem_num = 0;
        sem_b.sem_op = -1; /* P() */
        sem_b.sem_flg = 0;
        if (semop(sem_id, &sem_b, 1) == -1) {
              // error
                 return(0);
        }
        return(1);
    }

    // unlock semaphore
    static int V(int sem_id)
    {
        struct sembuf sem_b[1];
        sem_b.sem_num = 0;
        sem_b.sem_op = 1; /* V() */
        sem_b.sem_flg = 0;
        if (semop(sem_id, &sem_b, 1) == -1) {
              // error
            return(0);
        }
        return(1);
    }

    static int set_semval(int sem_id)  {
        // set to 1 (opened semaphore)
        if (semctl(sem_id, 0, SETVAL, 1) == -1) {
              // error
            return(0);
        }
        return(1);
    }

    static int get_val(int sem_id)
    {
        union semun sem_union;
        //sem_union.val = 0; ?
        return semctl(sem_id, 0, GETVAL, sem_union);
    }

动作循环:

// semaphores init
int mutex;
if ((mutex=semget(key+2, 1, 0666))>=0) {
    // semaphore exists
    fprintf(stderr,"semaphore exists for key %d\n", key+2);
}

if ((mutex=semget(key+2, 1, 0666 | IPC_CREAT)) == -1) { 
    exit(EXIT_FAILURE);
}
if (!set_semval(mutex)) {
    exit(EXIT_FAILURE);
}
fork()    // some times with good conditionals

// in some children
while(1) {
        P(mutex);   
        assert(get_val(mutex)==0); // always ok
        action();  // sometimes made by two processes at same time - fault
        V(mutex);
}   

请随时编辑我的问题。

非常感谢

【问题讨论】:

  • 您可能想测试 P() 和 V() 的返回值?
  • get_val()的定义是什么?你真的在测试正确的东西吗?
  • 发布一个完整的编译和运行的简化程序,以及它的输出。我的猜测是您没有正确初始化信号量。不要让我们猜测。
  • 发布了更多细节。 @edgar.holleis:stderr 是空的,所以 V 和 P 可以正常工作。

标签: c semaphore


【解决方案1】:

在你的“动作循环”中,如果你的信号量不存在,你会怎么做?

目前,semget 的第三个参数是 0666 或 PERMISSION_RW 常量。您可能想使用:

shmget(key, 1, PERMISSION_RW | IPC_CREAT);

这样,如果您的信号量不存在,它将创建一个。

【讨论】:

    【解决方案2】:

    所以错误在另一个地方......

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-23
      • 2021-03-20
      • 2019-10-02
      • 1970-01-01
      • 2019-04-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多