运行此程序后创建/涉及多少文件描述符 - 管道

时间:2016-11-01 17:48:11

标签: c pipe

从以下计划中

/***************************************************************************** 
 MODULE: popen.c
 *****************************************************************************/
#include <stdio.h>

int main(void)
{
        FILE *pipein_fp, *pipeout_fp;
        char readbuf[80];

        /* Create one way pipe line with call to popen() */
        if (( pipein_fp = popen("ls", "r")) == NULL)
        {
                perror("popen");
                exit(1);
        }

        /* Create one way pipe line with call to popen() */
        if (( pipeout_fp = popen("sort", "w")) == NULL)
        {
                perror("popen");
                exit(1);
        }

        /* Processing loop */
        while(fgets(readbuf, 80, pipein_fp))
                fputs(readbuf, pipeout_fp);

        /* Close the pipes */
        pclose(pipein_fp);
        pclose(pipeout_fp);

        return(0);
}

popen.c已汇编为my_program

以下是我对执行my_programpopen() forks&amp;和my_program后创建/涉及的文件描述符的理解。执行my_program进程,但子进程不继承ls的管道文件描述符。

所以,执行后,

1)仅为sort

创建写文件描述符

2)仅为my_program

创建读取文件描述符

3)读取和写入文件描述符是在ls中创建的,因为my_program写入sort&amp; my_programtype Output struct { Name string `json:"name"` }

读取

enter image description here

如上所示,这些是唯一涉及/创建的文件描述符吗?

注意:'in'&amp; 'out'只是这里使用的命名约定

1 个答案:

答案 0 :(得分:1)

来自 app.get('/levelCompleted/:id/:time', function (request, response) { var id = request.params.id; var time = parseInt(request.params.time); var u= game.getUserById(id); var k = "results.$.level"+(u.level); //I build the key to update dinamycally dbM.collection("results").update( {user:id, "results.game_id":u.game_id //u has its own game_id }, {$set: {k:time}} ); ... response.send(...); 的子进程与父进程具有完全相同的打开文件描述符集。

fork()调用使用popen()创建两个文件描述符;然后它执行pipe()。父进程安排管道的一端关闭,另一端转换为文件流(fork())。子进程关闭管道的另一端,并安排一端成为其执行的进程的标准输入(FILE *)或标准输出("w")(使用"r"dup()执行任务)。

您使用dup2()两次;你最终在父母中有2个开放描述符,而且瞬间有第三个。

  
      
  1. 当你说'父进程安排管道的一端关闭'时,你的意思是读取文件描述符(popen())?
  2.   

根据stdin的mode参数,父项中管道的两端之一立即关闭;另一个由popen()关闭。文件描述符“永远不会”是标准输入或标准输出的文件描述符 - 您必须经历非凡的旋转才能使其成为标准I / O通道之一。

  
      
  1. 通过pclose()完成所有流程,确保他们popen()确保他们使用stdout&amp;标准输入?
  2.   

每个管道都有一个读端和一个写端。拿dup();您的程序从popen("ls", "r")进程读取。它(ls)创建一个管道和叉子。在子节点中,管道的写入端连接到popen()stdout或者dup2()),并且在执行命令之前关闭管道的读取端。在父级中,管道的读取端“转换为”或“附加到”流(dup(),或多或少),并且管道的写入端关闭。在父进程中,管道永远不会连接到stdout或stdin。

在子进程中,标准输入或标准输出连接到管道,具体取决于fdopen()的mode参数。