【问题标题】:Semaphores unix c wait for zero信号量 unix c 等待零
【发布时间】:2015-06-21 21:13:53
【问题描述】:

我正在尝试了解如何在 unix 中执行等待零操作。我有这段代码,但它总是以与给定相同的值停止等待。

int main(void){

    int sem;
    struct sembuf sops[2];


    if((sem = semget(IPC_PRIVATE, 1,  IPC_CREAT | 0600))==-1){
        perror("Error semget");
        return 100;
    }

    fork();
    //printf("Empieza la accion\n");

    if(semctl(sem,0,SETVAL,2)==-1){
        printf("Error semctl\n");
        exit(100);
    }
    printf("Value: %d\n",semctl(sem,0,GETVAL));
    sops[0].sem_num=0;     
    sops[0].sem_op=-1;     
    sops[0].sem_flg=0;      

    //WAIT(0)   
    sops[1].sem_num=0;     
    sops[1].sem_op=0;     
    sops[1].sem_flg=0;
    printf("Value: %d\n",semctl(sem,0,GETVAL));

    if(semop(sem,&sops,2)<0) printf("Error semop\n");
    printf("Value: %d\n",semctl(sem,0,GETVAL));
    printf("End\n");

}

【问题讨论】:

  • 我相信这里的问题是你的第一个线程调用semop()这会将值递减到1,然后等待值变为0,但是直到第一个线程从semop()返回第二个不能输入它以再次减少它。您可能需要将操作分解为多个 semop() 调用。我对此并不积极...我从未使用过 semop(),我只是在阅读手册页。

标签: c unix semaphore ipcs


【解决方案1】:

Gcc 向我抱怨你的代码:

sem.c:37:警告:从不兼容的指针类型传递“semop”的参数 2 /usr/include/sys/sem.h:59:注意:预期为“struct sembuf *”,但参数类型为“struct sembuf (*)[2]”

这是它不喜欢的代码:

    if(semop(sem,&sops,2)<0) printf("Error semop\n");

如果我把它改成

    if(semop(sem,sops,2)<0) printf("Error semop\n");

然后 GCC 没有抱怨,程序在semop() 调用上无限期挂起,正如我所料。

特别注意semop() 将所有指定的操作作为一个原子组应用,或者根本不应用。如果两个进程指定的操作重叠,则您的程序只能通过 semop() 调用,这样首先执行两个递减,然后执行两个等待零。

如果我将SETVAL 操作移到fork() 调用之前,并且让每个进程执行两个单独的semop() 调用,一个是减少信号量,一个是等待让它变为零。

【讨论】:

  • 虽然是有效的评论,但这并不能回答所提出的问题。我承认他的英语不一定很清楚他在寻找什么(可能是 ESL)。我相信他遇到的问题正是你已经确认正在发生的事情——无限的等待。在我看来,他 fork()s 不正确地期望在两个线程都减少信号量值时等待完成——考虑到他目前的方法,我认为这是不可能的。
  • @mah,很公平。我已经更新了我的答案以解释挂起的原因,并提出解决方法。
  • 谢谢!但是在分叉之前移动 SETVAL 并不能解决无限等待的问题。我还需要做什么?
  • 我已经告诉过你了。每个进程必须通过 separate semop() 调用来执行递减操作和等待零操作。
猜你喜欢
  • 2011-12-08
  • 1970-01-01
  • 2014-10-21
  • 2019-08-04
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多