Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
关于close()和read()的关系_C_Process_Pipe - Fatal编程技术网

关于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]
UNIX不会将
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;
}