0x00思路

为了给TinyHTTPd源码分析打下基础,先写一个简单父子进程管道通信的样例

1,先定义,并绑定read,write函数和缓冲区,创建pipe管道数组(下标0对于读段,1对应写端,这是强制规定的)

2.父进程fork后,父子进程各有一套1中的变量,且代码执行是同步的,只不过储存空间不在一起,然后对父子进程的管道进行操作使之可以通信

0x01函数

write

#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);

将buf所指的内存中的count个字节,写入到文件描述符fd所指的文件中去。

read

number = read(handle, buffer ,n);

上述read调用函数中,各个参数的定义如下:

handle: 这是一个已经打开的文件标识符,表示从这个文件句柄所代表的文件读取数据。

buffer: 指缓冲区,即读取的数据会被放到这个缓冲区中去。

n: 表示调用一次read操作,应该读多少数量的字符。

number:表示系统实际所读取的字符数量。

pipe

头文件: #include<unistd.h>
函数原型:int pipe(int filedes[2]);

函数说明:pipe()会建立管道,并将文件描述词由参数filedes数组返回。

filedes[0]为管道里的读取端

filedes[1]则为管道的写入端。

返回值: 若成功则返回零,否则返回-1,错误原因存于errno中。

错误代码:

EMFILE 进程已用完文件描述词最大量

ENFILE 系统已无文件描述词可用。

EFAULT 参数 filedes 数组地址不合法。

fork

头文件:#include <unistd.h>#include<sys/types.h>
函数原型:pid_t fork( void);

创建一个新的进程。(pid_t 是一个宏定义,其实质是int 被定义在#include<sys/types.h>中)

fork后发生了什么

1.由fork创建的新进程被称为子进程(child process)。该函数被调用一次,但返回两次。两次返回的区别是子进程的返回值是0,

2.而父进程的返回值则是新进程(子进程)的进程 id。将子进程id返回给父进程的理由是:因为一个进程的子进程可以多于一个,没有一个函数使一个进程可以获得其所有子进程的进程id。

3.对子进程来说,之所以fork返回0给它,是因为它随时可以调用getpid()来获取自己的pid;也可以调用getppid()来获取父进程的id。(进程id为0的总是由交换进程使用,所以一个子进程的进程id不可能为0)。

4.fork之后,操作系统会复制一个与父进程完全相同的子进程。虽说是父子关系,但是在操作系统看来,他们更像兄弟关系,这2个进程共享代码空间,但是数据空间是互相独立的,子进程数据空间中的内容是父进程的完整拷贝,指令指针也完全相同,子进程拥有父进程当前运行到的位置(两进程的程序计数器pc值相同。也就是说,子进程是从fork返回处开始执行的)

5.但有一点不同,如果fork成功,子进程中fork的返回值是0,父进程中fork的返回值是子进程的进程号,如果fork不成功,父进程会返回错误。

可以这样想象,2个进程一直同时运行,而且步调一致,在fork之后,他们分别作不同的工作,也就是分岔了。

注意:

fork()函数主要是以父进程为蓝本复制一个进程,其ID号和父进程的ID号不同。对于结果fork出来的子进程的父进程ID号是执行fork()函数的进程的ID号;

例如:

父进程, fork返回值是:17025, ID:17024 ,父进程ID:16879

子进程, fork返回值是:0, ID:17025 ,父进程ID:17024

close

用这个函数来关闭管道的一端

0x02重要变量

1.result异常变量,用来进行判断一些函数的异常返回情况

2.pid进程变量(在fork函数的使用过程中很重要)

3.read/write buffer 在文件读写的时候创建缓冲区i

4.fd[2]pipe读写端数组 实现管道通信

0x03遇到的问题

1.对管道通信pipe读写端在不同进程下是怎样的关系不明确

2.fork函数两个返回值的利用实现父子进程过程不清楚

3.为什么TinyHTTPd要两个管道,而这个简单例子只需要一个管道

0x04解决问题

1.见下图

2.见下图

3.因为这个样例不需要双向通信,子进程并没有反馈给父进程

0x05代码

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<string.h>int main(void){// pid_t pid;int i=0;int result = -1;int fd[2],nbytes;char string[100];char readbuffer[80];//int *write_fd = &fd[1];//int *read_fd = &fd[0];printf("Please input data:");scanf("%s",string);result = pipe(fd);                  !!!!用fd建立了pip管道链接if(-1 == result){perror("pipe");return -1;}/*pid=fork();                              !!!!!!!父子进程分开if(-1 == pid) //此处为了验证父子进程是否创建成功,如果未创建成功,则返回-1{perror("fork");return -1;}else if(0 == pid)//如果是子进程{printf(“this is child %d\n”, getpid());close(*read_fd);//关掉子进程的读端,只剩下写端result = write(*write_fd,string,strlen(string));//向string写入,写入到文件描述符pipe写端return 0;}*/else//如果不是子进程{printf(“this is parent %d\n”, getpid());close(*write_fd);//关闭父进程的pip写端,只留下读端nbytes = read(*read_fd,readbuffer,sizeof(readbuffer)-1);//从read_fd中读入,先放入readbufferprintf("receive %d data:%s\n",nbytes,readbuffer);}
return 0;
}

父子进程管道通信(附简单样例)相关推荐

  1. 已知一个掺杂了多个数字字符的中文名拼音,去掉所有数字字符之后,形式为“名”+空格+“姓”;并且名和姓的首字母大写,其他小写,要求输出姓名全拼,且全为小写。(后附详细样例说明)

    已知一个掺杂了多个数字字符的中文名拼音,去掉所有数字字符之后,形式为"名"+空格+"姓":并且名和姓的首字母大写,其他小写,要求输出姓名全拼,且全为小写.(后附 ...

  2. JDBC 连接Hive 简单样例(开启Kerberos)

    今天在移动的云平台上通过jdbc连接hive,发现云平台使用了 kerberos的认证.与宁波实验环境不同. 发现一文解决了问题,转载如下: 原文地址:http://blog.csdn.net/zen ...

  3. 重要性采样(Importance Sampling)简介和简单样例实现

    重要性采样(Importance Sampling)简介和简单样例实现 在渲染领域,重要性采样这个术语是很常见的,但它究竟是什么呢?我们首先考虑这样的一种情况: 如果场景里有一点P,我们想计算P点的最 ...

  4. C语言单元测试之安装gtest教程及一个简单样例

    准备工作 安装包:gtest1.7.0版本(最新的1.8.0版本一直安装失败,1.7.0版本一次成功) 安装链接:百度网盘 https://pan.baidu.com/s/1mDy9sB3sBIMei ...

  5. K8S Yaml 详细说明及简单样例

    一.K8S Yaml 配置文件主要分为基本标签.元数据标签.资源内容 3 个部分 基本标签 apiVersion: v1 #必选,版本号,例如v1 kind: Pod #必选,Pod 元数据标签 me ...

  6. NASBench101-安装及简单样例使用指南

    NASBench101-安装及简单样例使用指南 github地址:https://github.com/google-research/nasbench paper原文地址:https://arxiv ...

  7. java 泛型向下转型_Java向上转型和向下转型(附具体样例)

    Java向上转型和向下转型(附具体样例) 熬夜整理的关于Java向上和向下转型的样例,很的通俗易懂哦~~~~ 一.向上转型 package com.sheepmu; class Animal { pu ...

  8. Argo Workflow简单样例——dag-阿里云开发者社区

    什么是Argo Workflow Argo Workflow是一个开源项目,为Kubernetes提供Container-native工作流程,主要通过Kubernetes CRD实现.它有四大特点: ...

  9. linux进程管道通信缺点,Linux进程通信(IPC)的方式详解

    前言:Linux进程通信的方式 什么是进程通信?进程通信是指进程之间交换信息 进程通信方式共有6种: 管道(pipe),包括流管道(s_pipe)和有名管道(named pipe) 信号(signal ...

最新文章

  1. pxeconfig 4.2.0 发布,PXE 首要启动设备
  2. String to Integer (atoi) leetcode java
  3. 【STL源码剖析读书笔记】【第5章】关联式容器之set、map、multiset和multimap
  4. [ZJOI2014] 星系调查(树上差分 + 数学推式子)
  5. P2290-[HNOI2004]树的计数【组合数,Prufer序列】
  6. scikit-learn流形学习手写数字可视化
  7. python纵向数据分析_python数据分析三个重要方法之:numpy和pandas
  8. led计数电路实验报告_至简设计系列_状态机实现LED交通灯2
  9. Iframe相关操作
  10. jdk完全卸载(亲测jdk1.7.0_80在win7)
  11. ERP知识普及连载(13)
  12. C/C++图书管理系统
  13. k2pbreed刷高恪教程_斐讯K2刷高恪固件教程,通过breed刷入,详细图文教程
  14. 岁月温柔-3 清明节医院复查,去昆明过冬是否会是一种奢望?
  15. 简单Python爬虫实例:抓取豆瓣热映电影信息
  16. js中的引号使用不正确导致js方法传入参数类型错误
  17. 阿里云机器的JVM内存调优经历(菜鸟必看,大神请绕道)
  18. 2414905-34-1,Thalidomide-O-PEG5-Tosyl它与亲核物质如胺、含羟基的分子反应
  19. 马云收购士兰微_根本停不下来!又一家国内半导体公司将被吞并!
  20. python第三章_Python学习(第三章)

热门文章

  1. 数字人事系统 java_我省税务系统全面推行数字人事管理
  2. 愤怒的小鸟-----------接口
  3. UC浏览器新版走新闻路线,酷似今日头条,腾讯模式再现!
  4. 论文查重出报告之后应该怎样修改?
  5. mysql 根据经纬度查询规定范围内符合坐标的店铺并优化查询的sql语句
  6. 阿里云企业版实例迁移工具最佳实践
  7. 女生宿舍-同名专辑《女生宿舍 Life Is Beautiful》
  8. Mega-Nerf学习笔记
  9. 低代码:助力乡村振兴事业开启“智慧模式”
  10. python心脏线绘制代码_C++和Java命令行绘制心形图代码分享