关于close()和read()的关系
为什么上面的代码最终会阻塞?但是如果我们删除注释并放置关于close()和read()的关系,c,process,pipe,C,Process,Pipe,为什么上面的代码最终会阻塞?但是如果我们删除注释并放置 int main() { char *msg="hello"; char buff[MAX]; int p[2]; pipe(p); int i,pid=fork(); if(pid>0){ //close(p[1]); read(p[0],buff, MAX); } else { printf("child exi
int main()
{
char *msg="hello";
char buff[MAX];
int p[2];
pipe(p);
int i,pid=fork();
if(pid>0){
//close(p[1]);
read(p[0],buff, MAX);
}
else
{
printf("child exiting\n");
}
}
那么,为什么代码会立即结束 创建管道后,它将有四个端点:
- 父进程中的读取端
p[0]
- 父进程中的写入端
p[1]
- 子进程中的读取端
p[0]
- 子进程中的写入端
p[1]
EOF
传递给读卡器,除非两端都已关闭,因为它知道管道仍然是可写的
当子进程退出时,它会关闭其一侧管道的两端。但是,父级仍然有一个可写端打开,因此从管道块读取,而不是向父级传递EOF
。这就是UNIX手册指示立即关闭管道未使用端的原因:
使用pipe(2)
和fork(2)
的应用程序应使用合适的close(2)
调用来关闭不必要的重复文件描述符;这样可以确保在适当的时候交付文件结尾和SIGPIPE
/EPIPE
下面是一个示例,说明如何在不关闭父端的p[1]
的情况下使程序不阻塞:
close(p[1])
#包括
#包括
#包括
#包括
#包括
void*write_管道(void*pp){
int*p=(int*)pp;
char msg[]=“来自另一个线程的你好!”;
写入(p[1],msg,sizeof(msg));
返回NULL;
}
int main()
{
字符buff[100];
int p[2];
管道(p);
int-pid=fork();
如果(pid>0){
pthread_t thread1;
pthread_创建(&thread1,NULL,&write_管道,(void*)p);
读取(p[0],浅黄色,100);
printf(“%s\n”,浅黄色);
printf(“父级退出\n”);
}
其他的
{
printf(“子项退出\n”);
}
返回0;
}
上面的代码从父进程中的线程写入管道的写入端,而不是从子进程写入。这也是管道的合法使用,说明了为什么UNIX不能传递
EOF
,除非父管道的写入端关闭。读取是一个阻塞调用,它仅在接收到EOF时返回。如果您不关闭管道的写入端,读取端将不会获得EOF,因此,程序将保持阻塞状态我觉得奇怪的是,这个好问题在我的原始代码中收到了一个downvoteIn,如果在子进程中关闭并在父进程中等待,父进程仍然会被阻塞。但是你告诉我,管道上的读取调用被阻塞了。只有发生以下两种情况之一,它才会完成:一些数据可供读取以返回调用方,或者管道已关闭closed@AchyutaAich对不起,一开始我不明白你的问题。我将尝试提出一个在父端使用未闭合端的示例。
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void* write_pipe(void* pp) {
int* p = (int*)pp;
char msg[] = "Hello from another thread!";
write(p[1], msg, sizeof(msg));
return NULL;
}
int main()
{
char buff[100];
int p[2];
pipe(p);
int pid=fork();
if(pid>0){
pthread_t thread1;
pthread_create (&thread1, NULL, &write_pipe, (void *)p);
read(p[0],buff, 100);
printf("%s\n", buff);
printf("parent exiting\n");
}
else
{
printf("child exiting\n");
}
return 0;
}