3

我试图了解如何在 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");

}
4

1 回答 1

1

Gcc 向我抱怨您的代码:

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

这是它不喜欢的代码:

    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()的调用,一个用于递减信号量,然后一个用于等待信号量变为零,您的程序将按照您的预期工作。

于 2015-04-15T19:17:19.643 回答