semop:错误的文件描述符

semop : Bad file descriptor

#define MAX 2

int main(){

    int mutex = semget(ftok("/usr",'P'),1,IPC_CREAT|0666);
    int wrt = semget(ftok("/usr",'Q'),1,IPC_CREAT|0666);

    if(mutex <= 0) perror("mutex");
    if(wrt <= 0) perror("wrt");

    if(semctl(mutex,0,SETVAL,1) <= 0) perror("mutex semctl");
    if(semctl(wrt,0,SETVAL,1) <= 0) perror("wrt semctl");

    struct sembuf sops;
    int pid1,pid2,readcount = 0,var=0;
    FILE* fp = fopen("buffer.txt","w");
    fprintf(fp,"%d",var);   
    fclose(fp);
    printf("File created. VAR is %d\n",var);
    pid1 = fork();

   if(!pid1){

        while(1){
            sleep(1);
            sops.sem_num = 0; sops.sem_op = -1; sops.sem_flg = 0;
        semop(mutex,&sops,1);

        // if(readcount == 0)
        if(readcount == 0){
            //  wait(wrt)
            sops.sem_num = 0; sops.sem_op = -1; sops.sem_flg = 0;
            if(semop(wrt,&sops,1) <= 0) perror("wrt in reader 1");
        }
        // readcount++
        readcount++;
        // signal(mutex)
        sops.sem_num = 0; sops.sem_op = 1; sops.sem_flg = 0;
        semop(mutex,&sops,1);

        // read()
        sleep(1.5);
        printf("First reader enters \n");
        fp = fopen("buffer.txt","r");
        fscanf(fp,"%d",&var);
        printf("Reader (%d) reads the value %d\n",getpid(),var);
        fclose(fp);
        printf("First reader leaves\n");
        sleep(1.5);


        // wait(mutex)
        sops.sem_num = 0; sops.sem_op = -1; sops.sem_flg = 0;
        semop(mutex,&sops,1);
        // readcount--;
        readcount--;
        // if(readcount == 0)
        if(readcount == 0){
            //  signal(wrt)
            sops.sem_num = 0; sops.sem_op = 1; sops.sem_flg = 0;
            semop(wrt,&sops,1);
        }
        // signal(mutex)
        sops.sem_num = 0; sops.sem_op = 1; sops.sem_flg = 0;
        semop(mutex,&sops,1);   
    }


}
else{
    pid2 = fork();
    if(!pid2){

        while(1){
            sleep(1);
            // wait(mutex)
            sops.sem_num = 0; sops.sem_op = -1; sops.sem_flg = 0;
            semop(mutex,&sops,1);
            // if(readcount == 0)
            if(readcount == 0){
                //  wait(wrt)
                sops.sem_num = 0; sops.sem_op = -1; sops.sem_flg = 0;
                if(semop(wrt,&sops,1) <= 0) perror("wrt in reader 1");
            }
            // readcount++
            readcount++;
            // signal(mutex)
            sops.sem_num = 0; sops.sem_op = 1; sops.sem_flg = 0;
            semop(mutex,&sops,1);


            // read()
            sleep(1);
            printf("Second reader enters\n");
            sleep(1);
            fp = fopen("buffer.txt","r");
            fscanf(fp,"%d",&var);
            printf("Reader (%d) reads the value %d\n",getpid(),var);
            sleep(1);
            fclose(fp);
            printf("Second reader leaves\n");
            sleep(1);


            // wait(mutex)
            sops.sem_num = 0; sops.sem_op = -1; sops.sem_flg = 0;
            semop(mutex,&sops,1);
            // readcount--;
            readcount--;
            // if(readcount == 0)
            if(readcount == 0){
                //  signal(wrt)
                sops.sem_num = 0; sops.sem_op = 1; sops.sem_flg = 0;
                semop(wrt,&sops,1);
            }
            // signal(mutex)
            sops.sem_num = 0; sops.sem_op = 1; sops.sem_flg = 0;
            semop(mutex,&sops,1);
        }
    }
    else{
        //struct sembuf sop;

        while(1){

            // wait(wrt)
            sops.sem_num = 0; sops.sem_op = -1; sops.sem_flg = 0;
            semop(wrt,&sops,1);

            // write
            sleep(1);
            //printf("%d Writer enters\n",time(0)%100); 
            fp = fopen("buffer.txt","w");
            fscanf(fp,"%d",&var);
            var++;
            sleep(1);
            printf("Writer (%d) writes the value %d\n",getpid(),var);
            fprintf(fp,"%d",&var);
            fclose(fp);
            sleep(1);
            printf("Writer leaves wrt %d\n",semctl(wrt,0,GETVAL,0));

            // signal(wrt)
            sops.sem_num = 0; sops.sem_op = 1; sops.sem_flg = 0;
            printf("wrt just before semop %d and op is %d\n",semctl(wrt,0,GETVAL,0),sops.sem_op);
            if(semop(wrt,&sops,1) <= 0) perror("wrt signal");
            printf("wrt %d\n",semctl(wrt,0,GETVAL,0));
        }
    }

}
}

以下代码是 读者-作者问题 的细微变化。在这个程序中,我尝试创建两个子进程(两个读者)。有一个父进程(编写器)。读者只是从名为 buffer.txt 的文件中读取值,而作者在该文件中写入一个值。

但在作者代码中,使用 semop()// signal(wrt) 代码出现错误 Bad File descriptor。因此,wrt 的值不会增加。请帮忙。

经过10个小时的艰苦奋斗,我想出了一个完美运行的解决方案,没有任何错误的死锁。

改变 1 : 在编写器的代码中,首先以读取模式打开文件,读取值,然后以写入模式打开文件,然后写入增量值。

这还不够,可能还会有死锁问题。

改变2: 我们还需要为 readcount 创建一个信号量,因为它们必须被两个子进程使用。