Семафоры Unix c ожиданием нуля

Я пытаюсь понять, как сделать ожидание нулевой операции в 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");

}

1 ответ

GCC жалуется мне на ваш код:

sem.c: 37: предупреждение: передача аргумента 2 'semop' из несовместимого типа указателя /usr/include/sys/sem.h:59: note: ожидается '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() вызывает, один, чтобы уменьшить семафор, а затем один, чтобы ждать, пока он станет нулевым.

Другие вопросы по тегам