Head First C 第十章 进程间通讯 建立管道

Head First C 第十章 进程间通讯 建立管道

咱们已经能够经过重定向的方式,将子进程的输出重定向到文件,但咱们想从进程中直接读取数据,如何使实现。python

用管道链接进程

咱们曾经用一个命令来链接进程,那就是管道:git

  • python fake_rss.py | grep 'naruto'

能够用管道把一个进程的输出链接到另外一个进程的输入。 管道两侧的命令是父子关系。github

  1. 命令行建立了父进程。
  2. 父进程在子进程中克隆出了fake_rss.py脚本。
  3. 父进程用管道把子进程的输出链接到本身的输入。
  4. 父进程运行grep命令。

若是想在c代码中,而不是命令行中实现管道链接,该怎么作呢。数组

在浏览器中打开连接

咱们要作如下两件事:浏览器

  1. 从python脚本的输出中获取连接
  2. 在浏览器中打开连接
如何建立管道

咱们要在进程中建立两条新的流,用于管道的读取与写入。函数

数据流
0 stdin
1 stdout
2 stderr
3 管道读取端
4 管道写入端
  1. pipe()函数创建管道 由于子进程要把数据发送到父进程里,因此要用管道链接子进程的标准输入父进程的标准输出。 咱们说过,每当打开数据流时,它都会加入描述符表。pipe()函数也是如此,它建立两条相连的数据流,并把它们加入描述符表中。 这样你只要从一条数据流中写入数据,就能从另外一条数据流中读取
  2. 描述符存放在一个包含两个元素的数组中
    int fd[2];
    	if (pipe(fd) == -1) {
    	    error("Can't create pipe");
    	}
  3. fd[1]写管道,fd[0]读管道 1. 在子进程中: - 须要关闭管道的fd[0]端 - 修改子进程的标准输出,让它指向fd[1]对应的数据流 由于子进程不会从管道中读取数据,子进程发送给标准输出的数据都会写入到管道中。 2. 在父进程中: - 须要关闭管道的fd[1]端,由于父进程不须要往管道中写入数据 - 修改父进程的标准输入,使其从描述符fd[0]的数据流中读取数据。
使用管道进行进程间通讯
  1. 对于子进程的操做
    if (pid == 0) {
    
        dup2(fd[1], 1);
        close(fd[0]);
        execlp("python", "python", "./fake_rss.py", NULL);

} 2. 父进程的操做c dup2(fd[0], 0); close(fd[1]); char line[255]; while (fgets(line, sizeof(line) / sizeof(char), stdin)) { if (line[strlen(line) - 1] == '\n') line[strlen(line) - 1] = 0; printf("Got url :%s\n", line);url

pid_t pid2 = fork();
if (pid2 == 0) {
  open_url(line);
}

} ``` 父进程要作的是: 1. 将标准输入stdin重定向到*fd[0]*的数据流。 2. 用一个while循环从stdin读入数据,判断条件为读入的结果(当执行脚本结束时会返回EOF,fgets()返回0,循环结束)。 3. 再fork()一次,用于建立多个子进程打开多个url。命令行

有名管道

有名管道是基于文件的管道,也叫作FIFO(First In First Out)文件。 由于基于文件的管道有名字,因此两个进程只要知道管道的名字就能用它来通讯,即便它们不是父子进程。 使用系统调用mkfifo()能够建立有名管道。code

代码

process communication with pipe进程

相关文章
相关标签/搜索