C 程序来演示 fork() 和 pipe()

简介: fork() 用于创建子进程。此子进程是原始(父)进程的副本。它是在类Unix操作系统上创建进程的主要方法。

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第6天,点击查看活动详情


fork() 用于创建子进程。此子进程是原始(父)进程的副本。它是在类Unix操作系统上创建进程的主要方法。


语法:

fork(); 
// 它不接受任何参数,而是返回整数值。它可以返回负、正或零整数值。
复制代码


pipe():用于Linux中的进程间通信。这是一个系统功能。


语法:

int pipe(int pipefd[2]);
复制代码

C 程序来演示 fork() 和 pipe():


编写 Linux C 程序以创建两个进程 P1 和 P2。P1 获取一个字符串并将其传递给 P2。P2 将接收到的字符串与另一个字符串连接起来,而不使用字符串函数,并将其发送回 P1 进行打印。


例子:

Other string is: forgeeks.org
Input  : www.haiyong
Output : www.haiyong.site
Input :  www.code.haiyong
Output : code.haiyong.site
复制代码


解释:

  • 要创建子进程,我们使用 fork()。fork() 返回 :
  • <0 无法创建子(新)进程
  • =0 表示子进程
  • >0 即子进程到父进程的进程 ID。当 >0 时,将执行父进程。
  • pipe() 用于将信息从一个进程传递到另一个进程。pipe() 是单向的,因此,对于进程之间的双向通信,可以设置两个管道,每个方向一个。


例:

int fd[2];
pipe(fd);
fd[0]; //-> 用于使用读端
fd[1]; //-> 用于使用写结束
复制代码


父进程内部: 我们首先关闭第一个管道的读取端 (fd1[0]),然后通过管道的写入端 (fd1[1]) 写入字符串。现在,父进程将到子进程完成。在子进程之后,父进程将关闭第二个管道的写入端(fd2[1]),并通过管道的读取端(fd2[0])读取字符串。


内部子进程: Child 通过关闭管道的写入端 (fd1[1]) 来读取父进程发送的第一个字符串,读取后连接两个字符串并通过 fd2 管道将字符串传递给父进程并退出。

输入

www.haiyong
复制代码


C程序演示 forke() 和 pipe() 的使用


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main()
{
  // 我们使用两个管道第一个管道从父级发送输入字符串第二个管道从子级发送连接字符串
  int fd1[2]; // 用于存放第一根管道的两端
  int fd2[2]; // 用于存放第二根管道的两端
  char fixed_str[] = "haiyong.site";
  char input_str[100];
  pid_t p;
  if (pipe(fd1) == -1) {
    fprintf(stderr, "Pipe Failed");
    return 1;
  }
  if (pipe(fd2) == -1) {
    fprintf(stderr, "Pipe Failed");
    return 1;
  }
  scanf("%s", input_str);
  p = fork();
  if (p < 0) {
    fprintf(stderr, "fork Failed");
    return 1;
  }
  // 父进程
  else if (p > 0) {
    char concat_str[100];
    close(fd1[0]); // 关闭第一根管道的读取端
    // 写入输入字符串并关闭第一个管道的写入端。
    write(fd1[1], input_str, strlen(input_str) + 1);
    close(fd1[1]);
    // 等待孩子发送字符串
    wait(NULL);
    close(fd2[1]); // 关闭第二个管道的写入端
    // 从孩子身上读取字符串,打印并关闭阅读端。
    read(fd2[0], concat_str, 100);
    printf("Concatenated string %s\n", concat_str);
    close(fd2[0]);
  }
  // 子进程
  else {
    close(fd1[1]); // 关闭第一个管道的写入端
    // 关闭first的写入端使用第一个管道读取字符串
    char concat_str[100];
    read(fd1[0], concat_str, 100);
    // 将固定字符串与其连接
    int k = strlen(concat_str);
    int i;
    for (i = 0; i < strlen(fixed_str); i++)
      concat_str[k++] = fixed_str[i];
    concat_str[k] = '\0'; // 字符串以“\0”结尾
    // 关闭两个读取端
    close(fd1[0]);
    close(fd2[0]);
    // 写入连接字符串并关闭写入结束
    write(fd2[1], concat_str, strlen(concat_str) + 1);
    close(fd2[1]);
    exit(0);
  }
}
复制代码


输出:


Concatenated string www.haiyong.site



目录
相关文章
|
Java Linux
使用jps强制关闭java进程
使用jps强制关闭java进程
1411 0
使用jps强制关闭java进程
|
存储 算法
Hash表经典操作与实践
文章探讨了Hash表在算法领域的应用,通过LeetCode上的实例题目展示了如何使用Hash表进行数据存在性判断、重复数据计数等操作,并强调了Hash表在提高查找效率和解决特定问题中的重要性。
Hash表经典操作与实践
|
JavaScript 调度
setTimeout和setImmediate以及process.nextTick的区别?
setTimeout和setImmediate以及process.nextTick的区别?
80 0
setTimeout和setImmediate以及process.nextTick的区别?
|
API Python
Python实现post请求虾皮shopee商品列表数据接口
Python实现post请求虾皮shopee商品列表数据接口
1353 0
|
PyTorch 算法框架/工具
PyTorch的nn.Linear()详解
从输入输出的张量的shape角度来理解,相当于一个输入为[batch_size, in_features]的张量变换成了[batch_size, out_features]的输出张量。
825 0
|
存储 缓存 C++
iOS-底层原理 15:dyld加载流程
iOS-底层原理 15:dyld加载流程
546 0
iOS-底层原理 15:dyld加载流程
|
Java
复制文件或文件夹Java方法
复制文件或文件夹Java方法
123 0
|
程序员 API 计算机视觉
思考:如何写出让同事难以维护的代码?doge
本文从【程序命名&注释】【数据类型&类&对象】【控制执行流程】和【程序/结构设计】四个方面梳理了一些真实案例,相信通过这些案例你能迅速get技能:如何写出让同事难以维护的代码doge。
|
小程序 程序员 测试技术
软件问题修复跟踪系统实战开发教程(上篇)
软件问题修复跟踪系统实战开发教程(上篇)
软件问题修复跟踪系统实战开发教程(上篇)
|
算法 Python
ML之xgboost:利用xgboost算法(自带方式)训练mushroom蘑菇数据集(22+1,6513+1611)来预测蘑菇是否毒性(二分类预测)
ML之xgboost:利用xgboost算法(自带方式)训练mushroom蘑菇数据集(22+1,6513+1611)来预测蘑菇是否毒性(二分类预测)
ML之xgboost:利用xgboost算法(自带方式)训练mushroom蘑菇数据集(22+1,6513+1611)来预测蘑菇是否毒性(二分类预测)