使用select(),read(),write()进行I / O多路复用

时间:2014-09-13 07:51:20

标签: c++ c

我正在尝试编写一个应用程序,它包含来自不同Child的Parent复用输入,使用select(),write()和read()和Pipe。

想为以下几点寻求建议:

  1. 当子write()时,父select()会检测并返回,即使孩子还在写(即write()阻塞尚未返回)?

  2. 如果child正在执行write(),而父read(),是否可能导致父进程读取不完整的消息?

  3. Q1&是否需要“保护”代码Q2?

    e.g。定义4字节标头以指示消息长度。父read()前4个字节来检查消息长度,然后循环和read()直到获得完全相同的长度。

  4. 仅举例说明,以下是父母&子代码段。我问的是,看看孩子中的不同buf_len是否会导致父母的问题。

    父代码段

    int MAX_LENGTH=10000;
    char buf[MAX_LENGTH];
    
    int pipeFd[2];
    pipe(pipeFd);
    
    //fork child code and create pipe codes skipped..
    
    fd_set pipeSet;
    int r, nbytes;
    
    close(pipeFd[1]);
    while (1){
       FD_ZERO(&pipeSet);
       FD_SET(pipeFd[0], &pipeSet);
       memset(buf, 0, MAX_LENGTH);
    
       r=select(pipeFd[0] + 1, &pipeSet, NULL, NULL, NULL);
       if(FD_ISSET(pipeFd[0], &pipeSet))
           nbytes=read(pipeFd, buf, MAX_LENGTH);
    }
    

    子代码分段

    close(pipeFd[0]);
    int buf_len;
    while (1){
       memset(buf, 0, MAX_LENGTH);
    
       //codes to get data from different means depending on child ID
       //e.g. msgget() from msg queue, user input... etc.
       //length of data varies
    
       write(pipeFd[1], buf, buf_len);
    }
    

1 个答案:

答案 0 :(得分:2)

  

当子write()时,父select()会检测并返回,即使孩子仍然在写(即write()阻塞还没有返回)?

只要接收器的套接字接收缓冲区中有数据,套接字就会变得可读。如果您在该套接字上选择以提高可读性,则选择()将返回。可能只收到一个字节。

  

如果child正在执行write(),而父read(),是否可能导致parent读取不完整的消息?

TCP中没有消息。父级总是可以读取比请求的数据少的数据。孩子当时在做什么是无关紧要的。

  

是"保护" Q1及其所需的代码Q2?

     

e.g。定义4字节标头以指示消息长度。父read()前4个字节检查消息长度,然后循环和read()直到获得完全相同的长度。

这不是使用多路复用I / O的正确方法。接收器应该读取,如果数据不完整,它应该返回到选择循环并等待另一个读取事件,再做一次读取等,直到数据完成。请注意,读取计数字以及读取数据时可能会发生不完整的读取。