【发布时间】:2022-11-26 14:09:55
【问题描述】:
我想使用进程间通信模拟机票预订系统管道专用
我想要 10 个与主服务器交互的客户端(父进程) 使用管道。
客户(子进程) 应该生成一个从 0-9 的随机数,它应该是航班号和 1-3 之间的座位数量。然后他们将在客户端传递上述请求,经过一些检查后,他们将被告知是否服务器可以容纳他们的座位(成功/失败).
我这里的问题是 10 个子进程确实生成随机航班 ID 和座位号,但父程序只会保留第一个生成的航班 ID10倍.
这是我第一次使用管道和文件描述符,所以可能会有很多错误,如果你能发现它们并帮助我解决这个问题,将不胜感激!
如果您需要对任何命令的进一步解释,请告诉我,我使用很多变量来进行求和和检查。(这只是与 IPC 相关的程序的一部分,如果您希望我编辑完整的程序,请与我联系)
for(j=0;j<=9;j++)
{
pid=fork();
if(pid<0)
{
perror("Error");
exit(1);
}
if(pid==0)
{
for(i=0;i<=9;i++)
{
close(fd1[j][0]);
close(fd2[j][0]);
seats = (rand() % 3)+1 ;
id= (rand()% 10);
printf("id %d seats %d\n",id,seats);
write(fd1[j][1],&id,sizeof(id));
write(fd2[j][1],&seats,sizeof(seats));
close(fd1[j][1]);
close(fd2[j][1]);
read(fd1[j][0],&good,sizeof(good));
if(good)
{
printf("success\n");
read(fd2[j][0],&flights[id].price,sizeof(flights[id].price));
close(fd2[j][0]);
}
else
{
printf("failure\n");
}
close(fd1[j][0]);}
exit(EXIT_FAILURE);
}
else
{
if(check==0){
struct fl flights[10]=
{
{0,(rand() % 5)+1,"Athens","Paris",20},
{1,(rand() % 5)+1,"London","Madrid",25},
{2,(rand() % 5)+1,"Moscow","Kiev",17},
{3,(rand() % 5)+1,"Manchester","Munchen",23},
{4,(rand() % 5)+1,"Budapest","Torino",15},
{5,(rand() % 5)+1,"Rome","Thessaloniki",21},
{6,(rand() % 5)+1,"Amsterdam","Lisbon",13},
{7,(rand() % 5)+1,"Sofia","Tallinn",10},
{8,(rand() % 5)+1,"Vienna","Bucharest",22},
{9,(rand() % 5)+1,"Copenhagen","Minsk",26}
};
check=1;}
for(j=0;j<=9;j++)
{
close(fd1[j][1]);
close(fd2[j][1]);
read(fd1[j][0],&id,sizeof(id));
read(fd2[j][0],&seats,sizeof(seats));
sun_krathseis=sun_krathseis+1;
sunolikes[id]=sunolikes[id]+1;
if(flights[id].available_seats>=seats)
{
kerdh=kerdh+flights[id].price;
flights[id].available_seats=flights[id].available_seats-seats;
epit[id]=epit[id]+1;
epitux_krat=epitux_krat+1;
good=1;
}
else
{
apot[id]=apot[id]+1;
good=0;
}
write(fd1[j][1],&good,sizeof(good));
if(good){
write(fd2[j][1],&flights[id].price,sizeof(flights[id].price));
close(fd2[j][1]);
}
close(fd1[j][1]);
}
waitpid=wait(NULL);
if(waitpid==-1)
{
perror("Error");
}
printf("Parent proccess ended \n");
}
}
}
【问题讨论】:
-
孩子似乎在循环的第一次迭代中关闭了 fds。如果他们已经关闭,他们不能在第二次迭代中写信给他们!将错误检查添加到
writes,您可能会看到invalid file descriptor错误。 -
但....?为什么孩子在循环的第一次迭代中退出?如果您在第一次迭代中退出,那么循环有什么意义?你的逻辑有些奇怪。
-
可能是我眼睛瞎了,但是
for() { ... } else {}是个语法错误。如果您使用更具可读性的缩进样式,将会有所帮助。单空格缩进不是一个好主意。 -
所以我应该避免关闭孩子的 fds?哪些 fds 是读的还是写的?
-
如果子进程向父进程写入,则子进程关闭读端并保持写端打开。
标签: c