关闭管道中未使用的末端
Closing unused end in pipes
我在操作系统课程中阅读了有关管道的内容,并编写了一些代码以更好地理解它。我对以下代码有疑问:
int fd[2]; // CREATING PIPE
pipe(fd);
int status;
int pid=fork();
if(pid==0)
{
// WRITER PROCESS
srand(123);
int arr[3]={1,2,3};
close(fd[0]); // CLOSE UNUSED(READING END)
for(int i=0;i<3;i++)
write(fd[1],&arr[i],sizeof(int));
close(fd[1]); // CLOSE WRITING END AFTER WRITING SO AS READ GETS THE EOF
}
else
{
// READER PROCESS
int arr[10];
int i=0;
int n_bytes;
//close(fd[1]); // CLOSE UNUSED(WRITING END)
while((n_bytes=read(fd[0],&arr[i],sizeof(int)))>0) // READIN IN A LOOP UNTIL END
i++;
close(fd[0]); // CLOSE READING END after reading
for(int j=0;j<i;j++)
cout<<arr[j]<<endl;
while(wait(&status)>0)
;
}
如果我 运行 这个,读取会被阻塞,如果我在 reader 进程中取消注释 close(fd[1]) 命令,代码 运行 没问题.
这意味着 close(fd[1]) 关闭写入端并且读取可以继续。
我的疑问是 即使我不关闭 reader 进程中的写入端,它也会在writer进程结束。那么为什么读取系统调用仍然被阻止?
两个问题:
首先是由于 operator precedence 循环条件 n_bytes=read(fd[0],&arr[i],sizeof(int))>0
实际上等于 n_bytes = (read(fd[0],&arr[i],sizeof(int)) > 0)
。也就是说,您将 比较 的值分配给变量 n_bytes
。要更正此问题,请在赋值周围添加额外的括号,如 (n_bytes=read(fd[0],&arr[i],sizeof(int)))>0
.
第二个问题是父进程和子进程都会循环调用wait
。您应该只在父进程中这样做以等待子进程。
最初,两个进程在管道的读写端都有打开的文件描述符。
OS 只会在所有打开的文件描述符都关闭时关闭管道的一端,所以如果你不在子进程中调用 close(fd[1])
,一个文件描述符将保持打开状态,管道的写端不会关闭,read
会阻塞等待永远不会到来的输入。
我在操作系统课程中阅读了有关管道的内容,并编写了一些代码以更好地理解它。我对以下代码有疑问:
int fd[2]; // CREATING PIPE
pipe(fd);
int status;
int pid=fork();
if(pid==0)
{
// WRITER PROCESS
srand(123);
int arr[3]={1,2,3};
close(fd[0]); // CLOSE UNUSED(READING END)
for(int i=0;i<3;i++)
write(fd[1],&arr[i],sizeof(int));
close(fd[1]); // CLOSE WRITING END AFTER WRITING SO AS READ GETS THE EOF
}
else
{
// READER PROCESS
int arr[10];
int i=0;
int n_bytes;
//close(fd[1]); // CLOSE UNUSED(WRITING END)
while((n_bytes=read(fd[0],&arr[i],sizeof(int)))>0) // READIN IN A LOOP UNTIL END
i++;
close(fd[0]); // CLOSE READING END after reading
for(int j=0;j<i;j++)
cout<<arr[j]<<endl;
while(wait(&status)>0)
;
}
如果我 运行 这个,读取会被阻塞,如果我在 reader 进程中取消注释 close(fd[1]) 命令,代码 运行 没问题. 这意味着 close(fd[1]) 关闭写入端并且读取可以继续。
我的疑问是 即使我不关闭 reader 进程中的写入端,它也会在writer进程结束。那么为什么读取系统调用仍然被阻止?
两个问题:
首先是由于 operator precedence 循环条件 n_bytes=read(fd[0],&arr[i],sizeof(int))>0
实际上等于 n_bytes = (read(fd[0],&arr[i],sizeof(int)) > 0)
。也就是说,您将 比较 的值分配给变量 n_bytes
。要更正此问题,请在赋值周围添加额外的括号,如 (n_bytes=read(fd[0],&arr[i],sizeof(int)))>0
.
第二个问题是父进程和子进程都会循环调用wait
。您应该只在父进程中这样做以等待子进程。
最初,两个进程在管道的读写端都有打开的文件描述符。
OS 只会在所有打开的文件描述符都关闭时关闭管道的一端,所以如果你不在子进程中调用 close(fd[1])
,一个文件描述符将保持打开状态,管道的写端不会关闭,read
会阻塞等待永远不会到来的输入。