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 创建一个信号量,因为它们必须被两个子进程使用。
#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 创建一个信号量,因为它们必须被两个子进程使用。