18 File Duplication and Pipes
1 Resource Duplication Across Forks
- 子进程是父进程的复制,在
fork
瞬间复制所有信息- 复制父进程的代码
- 复制父进程的状态,包含全部的内存空间,比如变量
/*shared_variable.c*/int main(int argc, char * argv[]){int status;pid_t cpid, pid;int i=0;while(1){ //loop and fork childrencpid = fork();if( cpid == 0 ){/* CHILD */pid = getpid();printf("Child: %d: i:%d\n", pid, i);//set i in child to something differnti *= 3;printf("Child: %d: i:%d\n", pid, i);_exit(0); //NO FORK BOMB!!!}else if ( cpid > 0){/* PARENT *///wait for childwait(&status);//print i after waitingprintf("Parent: i:%d\n", i);i++;if (i > 5){ break; //break loop after 5 iterations}}else{/* ERROR */perror("fork");return 1;}//pretty printprintf("--------------------\n");}return 0;
}
>./shared_variables
Child: 3833: i:0
Child: 3833: i:0
Parent: i:0
--------------------
Child: 3834: i:1
Child: 3834: i:3
Parent: i:1
--------------------
Child: 3835: i:2
Child: 3835: i:6
Parent: i:2
--------------------
Child: 3836: i:3
Child: 3836: i:9
Parent: i:3
--------------------
Child: 3837: i:4
Child: 3837: i:12
Parent: i:4
--------------------
Child: 3838: i:5
Child: 3838: i:15
Parent: i:5
1.1 File Descriptor’s across Forks
- 子复制父的文件描述符
- 父子同时对文件进行读写,共享
offset
/*shared_file.c*/
int main(int argc, char * argv[]){int fd, status;pid_t cpid;char c;if ( argc < 2){fprintf(stderr, "ERROR: Require path\n");return 1;}//shared between all children and parentif( (fd = open(argv[1], O_RDONLY)) < 0){perror("open");return 1;}while (1){cpid = fork();if( cpid == 0 ){/* CHILD *///try and read 1 byte from fileif( read(fd, &c, 1) > 0){printf("c: %c\n", c); // print the char_exit(0); //exit with status 0 on sucess read}else{//no more to read_exit(1); //exit with status 1 on failed read}}else if ( cpid > 0){/* PARENT *///wait for child to read firstwait(&status);//if exit status 1, break the loop, no more to readif( WEXITSTATUS(status) ){break; }//now parent reads a byteif( read(fd, &c, 1) > 0){printf("p: %c\n", c); // print the char}}else{/* ERROR */perror("fork");return 1;}}//done reading the fileclose(fd);return 0;
}
2 Inter-Process Communication and Pipes
- pipeline是进程之间外部通讯(一个进程,接收另一个进程执行的结果),pipe是进程内部通讯
int main(int argc, char * argv[]){//print hello world through a pipe!char hello[] = "Hello World!\n";char c;int pfd[2]; //pfd[0] reading end of pipe//pfd[1] writing end of pipe//open the pipeif( pipe(pfd) < 0){perror("pipe");return 1;}//write hello world to pipewrite(pfd[1], hello, strlen(hello));//close write end of pipeclose(pfd[1]);//read hello world from pipe, write to stdoutwhile( read(pfd[0], &c, 1)){write(1, &c, 1);}//close the read end of the pipeclose(pfd[0]);return 0;
}
2.2 Pipes Bursting! and Blocking!
- O.S. and the C standard library provides some amount of buffering on reads and writes. (C库和操作系统读写都有buffer)
- pipe就是kernel中的buffer
- when the pipe is full, the write will block.
- fcntl() or file descriptor control.通过fd来改变buffer的属性
fcntl(pfd[1], F_SETFL, O_NONBLOCK);
/*pipe_block.c*/
int main(int argc, char * argv[]){char c = 'A';int i;int pfd[2]; //pfd[0] reading end of pipe//pdf[1] writing end of pipe//open the pipeif( pipe(pfd) < 0){perror("pipe");return 1;}//write A's to pipe until it's fulli = 0;while( write(pfd[1], &c, 1) > 0){printf("%d\n",i);i++;}perror("write");//close write end of pipeclose(pfd[1]);//read from pipe?!?while( read(pfd[0], &c, 1)){write(1, &c, 1);}close(pfd[0]);return 0;
}
2.3 Inter Process Pipes
1.子进程复制父进程,所以pipe对应的文件描述符也会被复制
/*pipe_hello_to_child.c*/
int main(int argc, char * argv[]){//print hello world through a pipe! To child!char hello[] = "Hello World!\n";char c;int pfd[2]; //pfd[0] reading end of pipe//pfd[1] writing end of pipepid_t cpid;int status;//open a pipe, pfd[0] for reading, pfd[1] for writingif ( pipe(pfd) < 0){perror("pipe");return 1;}cpid = fork();if( cpid == 0 ){/* CHILD *///close the writing end in childclose(pfd[1]);//try and read 1 byte from pipe, write byte stdoutwhile( read(pfd[0], &c, 1) > 0){write(1, &c,1); }//close pipeclose(pfd[0]);_exit(0); }else if ( cpid > 0){/* PARENT *///close reading end in parentclose(pfd[0]);//write hello world to pipewrite(pfd[1], hello, strlen(hello));//close the pipeclose(pfd[1]);//wait for childwait(&status);}else{/* ERROR */perror("fork");return 1;}return 0;
}
3 Duplicating File Descriptor and Pipelines
1.pipe 是通过文件描述符来实现进程内部通讯
2.pipline则是通过stdout和stdin来进程进程外部通讯
3.1 Duplicating a File Descriptor
int dup2(int filedes, int filedes2);
- duplicate the file descriptor fildes onto the file descriptor filedes2
- read and write from fildes2 now, it would be the same as reading and writing from filedes
/*hello_dup.c*/
int main(int argc, char * argv[]){//print hello world to a file with dupint fd;//check argsif ( argc < 2){fprintf(stderr, "ERROR: Require destination path\n");return 1;}//open destination fileif( (fd = open(argv[1], O_WRONLY | O_TRUNC | O_CREAT , 0644)) < 0){perror("open");return 1;}//close standard outclose(1);//duplicate fd to stdoutdup2(fd, 1);//print to stdout, which is now duplicated to fdprintf("Hello World!\n");return 0;
}
3.2 Setting up a pipeline
/*pipe_dup.c*/int main(int argc, char * argv[]){int status;int pfd[2];pid_t cpid;char c;//open a pipe, pfd[0] for reading, pfd[1] for writingif ( pipe(pfd) < 0){perror("pipe");return 1;}//Setup a pipe between child 1 and child 2, like:// parent | childcpid = fork();if( cpid == 0 ){/* CHILD 1*///close stdinclose(0);//duplicate reading end to stdindup2(pfd[0], 0);//close the writing endclose(pfd[1]);//try and read 1 byte from stding and write stdoutwhile( read(0, &c, 1) > 0){ //stdin now pipe!write(1, &c,1); //this is still stdout}exit(0);} else if ( cpid > 0){/* PARENT *///close stdoutclose(1);//duplicate writing end to stdoutdup2(pfd[1], 1);//close reading end close(pfd[0]);//read and read 1 byte from stdin, write byte to pipewhile( read(0,&c,1) > 0){write(1, &c, 1);}//close the pipe and stdoutclose(pfd[1]);close(1);//wait for childwait(&status);}else{/* ERROR */perror("fork");return 1;}return 0;
}
18 File Duplication and Pipes相关推荐
- version libmysqlclient_18 not defined in file libmysqlclient.so.18 with link time reference
在运行php -m时报错: PHP Warning: PHP Startup: Unable to load dynamic library 'mysqli.so' (tried: /usr/lib ...
- File类 判断功能和获取功能
1 package cn.zmh.File; 2 3 import java.io.File; 4 /* 5 * 6 * File判断功能 7 * 8 * */ 9 public class File ...
- JAVA基础--IO输入输出(File使用)17
一. File中的方法 1. 列举方法 1 /* 2 * 获取指定目录以及子目录下的所有文件和文件夹 3 */ 4 public class ListFilesDemo { 5 public sta ...
- Java:File和IO流
18 File(18-19) IO:对硬盘的文件进行读写 File:对(文件/文件夹)进行创建,删除等,表示要读写的(文件/文件夹)在哪 18.1 File构造方法 方法名 说明 File(Stri ...
- [canvas]空战游戏1.18
空战游戏到今天可以玩了,玩法还是方向键(或AWSD)控制飞机位置,空格键开炮,吃五星升级,被敌机打中降级直到击落,与敌机相撞则GG. 点此下载程序1.16版,用CHrome打开index.html试玩 ...
- file Android close,file close是什么意思
1. People are getting close to him, long-term customers with the file exchange, interaction, the blo ...
- C++ zip压缩库使用
这个压缩库,主要是用来解压和压缩相关文件使用,好处就是引入比较方便,而且极其易使用,方便用户操作. 首先是引入这四个文件,相关代码如下: 首先是zip.h头文件 #ifndef _zip_H #def ...
- 子进程及时知道父进程已经退出的最简单方案
[精彩] 子进程及时知道父进程已经退出的最简单方案? http://www.chinaunix.net 作者:yuonunix 发表于:2003-10-31 10:14:14 [发表评论] [查看原 ...
- android有用的命令
转载请指明出处:草帽的后花园 文件1:下载 Android Tools详解 aapt aapt即Android Asset Packaging Tool , 在SDK的platform-tools目录 ...
最新文章
- web自适应尺寸方法
- 【内推】滴滴出行视觉计算组招聘算法实习生
- UA MATH636 信息论9 Berlekamp-Welch算法
- mysql大量数据插入探讨(量变引起质变)
- Java中使用Jedis连接Redis对List进行操作的常用命令
- Mybatis报错:nested exception is org.apache.ibatis.binding.BindingException: Parameter ‘XXX‘ not found
- “大团队”和“敏捷开发”,谁说不可兼得?
- 没毛病!00后和90后成为暑期出游两大主力群体
- php自定义tcp协议,如何实现自定义协议?
- lua调用shell 脚本
- 数据结构与算法学习笔记之 提高读取性能的链表(上)
- 【NOIP2003】【Luogu1044】栈
- mysql常用数据操作之查
- 126 MySQL存储引擎概述
- centos绑定多个ip CentOS一个网卡设置多个IP
- 使用Mac的十大最好用神器
- android手机截图 视频,安卓Android手机相册视频如何隐藏
- 齐齐哈尔计算机应用软件学校,齐齐哈尔职业学院计算机应用技术专业介绍
- npm 同时安装同一个包的不同版本(npm@6.9 alias)
- rrpp协议如何修改_RRPP单环
热门文章
- linux创建名称为学号的文件,Linux操作系统下用户管理及文件管理.doc
- 微课|中学生可以这样学Python(7.3.3节):成员方法、类方法、静态方法
- Python爬虫扩展库scrapy选择器用法入门(一)
- c51单片机蜂鸣器程序C语言响,单片机蜂鸣器响生日快乐编程程序
- django和mysql如何建模_Django中的多个数据库和多个模型
- php fstat,PHP fstat( )用法及代码示例
- xshell连接成功但无法输入命令_如何解决cisco设备无法进入系统问题?
- 五分钟学会python_关于五分钟学Python系列视频
- 力扣904,水果成篮(JavaScript)
- 怎样让电脑速度变快_电脑常用软件推荐