简体   繁体   English

为什么父进程在ETmode下无法从pipe读取数据

[英]why the parent progress can't read the data from pipe in the ETmode

eh

Here I want to wirte data to pipe filedescriptors in the child progress.在这里,我想将数据写入子进程中的 pipe 文件描述符。

And read data form pipe in the parent progress.并在父进程中读取 pipe 的数据。

because i'm learning the ET mode,so I write 10 characters to the pipe, the sleep 2 seconds, and read 5 characters from the pipe in the same time.因为我正在学习ET模式,所以我将10个字符写入pipe,睡眠2秒,同时从pipe读取5个字符。

however the result is然而结果是

res 1
aaaa

I want to know how can I do to make the result like我想知道我该怎么做才能使结果像

res 1
aaaa
res 1
bbbb
...
make it can read the later charactes.
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<unistd.h>
#include<sys/epoll.h>
#include<iostream>
#include<fcntl.h>
#include"wrap.h"
#define MAXLINE 10

using namespace std;

int setnonblocking(int fd){
    int old_option = fcntl(fd, F_GETFL);
    int new_option = old_option|O_NONBLOCK;
    fcntl(fd, F_SETFL, new_option);
    return old_option;
}


int main(int argc, char* argv[]){
    int efd, i;
    int pfd[2];
    pid_t pid;
    char writebuf[MAXLINE], ch = 'a', readbuf[MAXLINE];
    pipe(pfd);
    pid = fork();

    if(pid == 0){       // child progress
        Close(pfd[0]);  //close read port
        while(true){
            for(i = 0;i<MAXLINE/2;i++){
                writebuf[i] = ch;
            }
            writebuf[i-1] = '\n';
            ch++;

            for(;i<MAXLINE;i++){
                writebuf[i] = ch;
            }
            writebuf[i-1] = '\n';
            ch++;

            Write(pfd[1], writebuf, sizeof(writebuf));
            setnonblocking(pfd[1]);
            sleep(2);
        }
        Close(pfd[1]);
    }
    else if(pid > 0){
        struct epoll_event event;
        struct epoll_event resevent[10];
        int res, len;

        Close(pfd[1]);              //close read-end of pipe
        efd = epoll_create(10);

        event.events = EPOLLIN|EPOLLET;
        // event.events = EPOLLIN;

        event.data.fd = pfd[0];
        epoll_ctl(efd, EPOLL_CTL_ADD, pfd[0], &event);
        setunonblocking(pfd[0]);
        while(1){
            res = epoll_wait(efd, resevent, 10, -1);
            printf("res %d\n", res);
            
            if(resevent[0].data.fd == pfd[0]){
                len = Read(pfd[0], readbuf, MAXLINE/2); 
                Write(STDOUT_FILENO, readbuf, len);
            }
        }

        Close(pfd[0]);
        Close(efd);
    }else{
        perror("fork");
        exit(-1);
    }
    return 0;
}

This scenario is explicitly mentioned in the epoll manual page : You use edge triggering, read only part of the data, and then wait again which will block.这种情况在epoll手册页中明确提到:您使用边缘触发,只读取部分数据,然后再次等待会阻塞。

One suggested solution is to make the descriptor non-blocking (which you forget to do) and read in a loop until read returns with the EAGAIN error.一种建议的解决方案是使描述符成为非阻塞(您忘记这样做)并在循环中读取,直到read返回EAGAIN错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM