当前位置:首页 >> 信息与通信 >>

进程通信—管道


1、 管道概述及相关 API 应用 、
1.1 管道相关的关键概念
管道是 Linux 支持的最初 Unix IPC 形式之一,具有以下特点: ? 管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管 道; ? 只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程); ? 单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件

,但 它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系 统,并且只存在与内存中。 ? 数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。写入的 内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。

1.2 管道的创建: 管道的创建:
#include <unistd.h> int pipe(int fd[2])

该函数创建的管道的两端处于一个进程中间,在实际应用中没有太大意义,因此,一个进程 在由 pipe()创建管道后,一般再 fork 一个子进程,然后通过管道实现父子进程间的通信(因 此也不难推出,只要两个进程中存在亲缘关系,这里的亲缘关系指的是具有共同的祖先,都 可以采用管道方式来进行通信)。

1.3 管道的读写规则: 管道的读写规则:
管道两端可分别用描述字 fd[0]以及 fd[1]来描述,需要注意的是,管道的两端是固定了任务 的。即一端只能用于读,由描述字 fd[0]表示,称其为管道读端;另一端则只能用于写,由 描述字 fd[1]来表示,称其为管道写端。如果试图从管道写端读取数据,或者向管道读端写 入数据都将导致错误发生。一般文件的 I/O 函数都可以用于管道,如 close、read、write 等 等。 从管道中读取数据: ? 如果管道的写端不存在,则认为已经读到了数据的末尾,读函数返回的读出字节数 为 0; ? 当管道的写端存在时,如果请求的字节数目大于 PIPE_BUF,则返回管道中现有的 数据字节数,如果请求的字节数目不大于 PIPE_BUF,则返回管道中现有数据字节 数(此时,管道中数据量小于请求的数据量);或者返回请求的字节数(此时,管 道中数据量不小于请求的数据量)。注:(PIPE_BUF 在 include/linux/limits.h 中定 义,不同的内核版本可能会有所不同。Posix.1 要求 PIPE_BUF 至少为 512 字节, red hat 7.2 中为 4096)。 关于管道的读规则验证:
/************** * readtest.c * **************/ #include <unistd.h>

#include <sys/types.h> #include <errno.h> main() { int pipe_fd[2]; pid_t pid; char r_buf[100]; char w_buf[4]; char* p_wbuf; int r_num; int cmd;

memset(r_buf,0,sizeof(r_buf)); memset(w_buf,0,sizeof(r_buf)); p_wbuf=w_buf; if(pipe(pipe_fd)<0) { printf("pipe create error\n"); return -1; }

if((pid=fork())==0) { printf("\n"); close(pipe_fd[1]); sleep(3);//确保父进程关闭写端 r_num=read(pipe_fd[0],r_buf,100); printf( "read num is %d the data read from the pipe is %d\n",r_num,atoi(r_buf));

close(pipe_fd[0]); exit(); } else if(pid>0) { close(pipe_fd[0]);//read strcpy(w_buf,"111"); if(write(pipe_fd[1],w_buf,4)!=-1) printf("parent write over\n"); close(pipe_fd[1]);//write printf("parent close fd[1] over\n"); sleep(10); } } /**************************************************

* 程序输出结果: * parent write over * parent close fd[1] over * read num is 4 * 附加结论: * 管道写端关闭后,写入的数据将一直存在,直到读出为止. ****************************************************/ the data read from the pipe is 111

向管道中写入数据: ? 向管道中写入数据时,linux 将不保证写入的原子性,管道缓冲区一有空闲区域,写 进程就会试图向管道写入数据。如果读进程不读走管道缓冲区中的数据,那么写操 作将一直阻塞。 注:只有在管道的读端存在时,向管道中写入数据才有意义。否则,向管道中写入 数据的进程将收到内核传来的 SIFPIPE 信号,应用程序可以处理该信号,也可以忽 略(默认动作则是应用程序终止)。 对管道的写规则的验证 1:写端对读端存在的依赖性
#include <unistd.h> #include <sys/types.h> main() { int pipe_fd[2]; pid_t pid; char r_buf[4]; char* w_buf; int writenum; int cmd;

memset(r_buf,0,sizeof(r_buf)); if(pipe(pipe_fd)<0) { printf("pipe create error\n"); return -1; }

if((pid=fork())==0) { close(pipe_fd[0]); close(pipe_fd[1]); sleep(10); exit(); } else if(pid>0)

{ sleep(1); //等待子进程完成关闭读端的操作

close(pipe_fd[0]);//write w_buf="111"; if((writenum=write(pipe_fd[1],w_buf,4))==-1) printf("write to pipe error\n"); else printf("the bytes write to pipe is %d \n", writenum);

close(pipe_fd[1]); } }

则输出结果为:Broken pipe,原因就是该管道以及它的所有 fork()产物的读端都已经被关闭。 如果在父进程中保留读端,即在写完 pipe 后,再关闭父进程的读端,也会正常写入 pipe, 读者可自己验证一下该结论。因此,在向管道写入数据时,至少应该存在某一个进程,其中 管道读端没有被关闭,否则就会出现上述错误(管道断裂,进程收到了 SIGPIPE 信号,默认 动作是进程终止) 对管道的写规则的验证 2:linux 不保证写管道的原子性验证
#include <unistd.h> #include <sys/types.h> #include <errno.h> main(int argc,char**argv) { int pipe_fd[2]; pid_t pid; char r_buf[4096]; char w_buf[4096*2]; int writenum; int rnum; memset(r_buf,0,sizeof(r_buf)); if(pipe(pipe_fd)<0) { printf("pipe create error\n"); return -1; }

if((pid=fork())==0) { close(pipe_fd[1]); while(1) { sleep(1);

rnum=read(pipe_fd[0],r_buf,1000); printf("child: readnum is %d\n",rnum); } close(pipe_fd[0]);

exit(); } else if(pid>0) { close(pipe_fd[0]);//write memset(r_buf,0,sizeof(r_buf)); if((writenum=write(pipe_fd[1],w_buf,1024))==-1) printf("write to pipe error\n"); else printf("the bytes write to pipe is %d \n", writenum); writenum=write(pipe_fd[1],w_buf,4096); close(pipe_fd[1]); } } 输出结果: the bytes write to pipe 1000 the bytes write to pipe 1000 the bytes write to pipe 1000 the bytes write to pipe 1000 the bytes write to pipe 1000 the bytes write to pipe 120 //注意,此行输出说明了写入的非原子性 the bytes write to pipe 0 the bytes write to pipe 0 ...... //注意,此行输出说明了写入的非原子性

结论: 写入数目小于 4096 时写入是非原子的! 如果把父进程中的两次写入字节数都改为 5000,则很容易得出下面结论: 写入管道的数据量大于 4096 字节时,缓冲区的空闲空间将被写入数据(补齐),直到写完 所有数据为止,如果没有进程读数据,则一直阻塞。

1.4 管道应用实例: 管道应用实例:
实例一: 实例一:用于 shell 管道可用于输入输出重定向,它将一个命令的输出直接定向到另一个命令的输入。比如,当 在某个 shell 程序(Bourne shell 或 C shell 等)键入 who│wc -l 后,相应 shell 程序将创建 who 以及 wc 两个进程和这两个进程间的管道。考虑下面的命令行: $kill -l 运行结果见 附一。 $kill -l | grep SIGRTMIN 运行结果如下:

30) SIGPWR 34) SIGRTMIN+2 38) SIGRTMIN+6 42) SIGRTMIN+10 46) SIGRTMIN+14

31) SIGSYS 35) SIGRTMIN+3 39) SIGRTMIN+7 43) SIGRTMIN+11 47) SIGRTMIN+15

32) SIGRTMIN 36) SIGRTMIN+4 40) SIGRTMIN+8 44) SIGRTMIN+12 48) SIGRTMAX-15

33) SIGRTMIN+1 37) SIGRTMIN+5 41) SIGRTMIN+9 45) SIGRTMIN+13 49) SIGRTMAX-14

实例二:用于具有亲缘关系的进程间通信 实例二: 下面例子给出了管道的具体应用, 父进程通过管道发送一些命令给子进程, 子进程解析命令, 并根据命令作相应处理。
#include <unistd.h> #include <sys/types.h> main() { int pipe_fd[2]; pid_t pid; char r_buf[4]; char** w_buf[256]; int childexit=0; int i; int cmd;

memset(r_buf,0,sizeof(r_buf)); if(pipe(pipe_fd)<0) { printf("pipe create error\n"); return -1; } if((pid=fork())==0) //子进程:解析从管道中获取的命令,并作相应的处理 { printf("\n"); close(pipe_fd[1]); sleep(2);

while(!childexit) { read(pipe_fd[0],r_buf,4); cmd=atoi(r_buf); if(cmd==0) { printf("child: receive command from parent over\n now child process exit\n"); childexit=1; }

else if(handle_cmd(cmd)!=0) return; sleep(1); } close(pipe_fd[0]); exit(); } else if(pid>0) //parent: send commands to child { close(pipe_fd[0]); w_buf[0]="003"; w_buf[1]="005"; w_buf[2]="777"; w_buf[3]="000"; for(i=0;i<4;i++) write(pipe_fd[1],w_buf[i],4); close(pipe_fd[1]); } } //下面是子进程的命令处理函数(特定于应用): int handle_cmd(int cmd) { if((cmd<0)||(cmd>256)) //suppose child only support 256 commands { printf("child: invalid command \n"); return -1; } printf("child: the cmd from parent is %d\n", cmd); return 0; }

1.5 管道的局限性
管道的主要局限性正体现在它的特点上: ? 只支持单向数据流; ? 只能用于具有亲缘关系的进程之间; ? 没有名字; ? 管道的缓冲区是有限的(管道制存在于内存中,在管道创建时,为缓冲区分配一个 页面大小); ? 管道所传送的是无格式字节流,这就要求管道的读出方和写入方必须事先约定好数 据的格式,比如多少字节算作一个消息(或命令、或记录)等等;

回页首

2、 有名管道概述及相关 API 应用 、
2.1 有名管道相关的关键概念
管道应用的一个重大限制是它没有名字,因此,只能用于具有亲缘关系的进程间通信,在有 名管道(named pipe 或 FIFO)提出后,该限制得到了克服。FIFO 不同于管道之处在于它 提供一个路径名与之关联,以 FIFO 的文件形式存在于文件系统中。这样,即使与 FIFO 的 创建进程不存在亲缘关系的进程, 只要可以访问该路径, 就能够彼此通过 FIFO 相互通信 (能 够访问该路径的进程以及 FIFO 的创建进程之间),因此,通过 FIFO 不相关的进程也能交 换数据。值得注意的是,FIFO 严格遵循先进先出(first in first out),对管道及 FIFO 的读 总是从开始处返回数据,对它们的写则把数据添加到末尾。它们不支持诸如 lseek()等文件 定位操作。

2.2 有名管道的创建
#include <sys/types.h> #include <sys/stat.h> int mkfifo(const char * pathname, mode_t mode)

该函数的第一个参数是一个普通的路径名,也就是创建后 FIFO 的名字。第二个参数与打开 普通文件的 open()函数中的 mode 参数相同。 如果 mkfifo 的第一个参数是一个已经存在 的路径名时, 会返回 EEXIST 错误, 所以一般典型的调用代码首先会检查是否返回该错误, 如果确实返回该错误,那么只要调用打开 FIFO 的函数就可以了。一般文件的 I/O 函数都可 以用于 FIFO,如 close、read、write 等等。

2.3 有名管道的打开规则
有名管道比管道多了一个打开操作:open。 FIFO 的打开规则: 如果当前打开操作是为读而打开 FIFO 时,若已经有相应进程为写而打开该 FIFO,则当前 打开操作将成功返回;否则,可能阻塞直到有相应进程为写而打开该 FIFO(当前打开操作 设置了阻塞标志);或者,成功返回(当前打开操作没有设置阻塞标志)。 如果当前打开操作是为写而打开 FIFO 时,如果已经有相应进程为读而打开该 FIFO,则当 前打开操作将成功返回;否则,可能阻塞直到有相应进程为读而打开该 FIFO(当前打开操 作设置了阻塞标志);或者,返回 ENXIO 错误(当前打开操作没有设置阻塞标志)。 对打开规则的验证参见 附 2。

2.4 有名管道的读写规则
从 FIFO 中读取数据: 约定:如果一个进程为了从 FIFO 中读取数据而阻塞打开 FIFO,那么称该进程内的读操作 为设置了阻塞标志的读操作。 ? 如果有进程写打开 FIFO,且当前 FIFO 内没有数据,则对于设置了阻塞标志的读操 作来说,将一直阻塞。对于没有设置阻塞标志读操作来说则返回-1,当前 errno 值 为 EAGAIN,提醒以后再试。

对于设置了阻塞标志的读操作说,造成阻塞的原因有两种:当前 FIFO 内有数据, 但有其它进程在读这些数据;另外就是 FIFO 内没有数据。解阻塞的原因则是 FIFO 中有新的数据写入,不论信写入数据量的大小,也不论读操作请求多少数据量。 ? 读打开的阻塞标志只对本进程第一个读操作施加作用,如果本进程内有多个读操作 序列,则在第一个读操作被唤醒并完成读操作后,其它将要执行的读操作将不再阻 塞,即使在执行读操作时,FIFO 中没有数据也一样(此时,读操作返回 0)。 ? 如果没有进程写打开 FIFO,则设置了阻塞标志的读操作会阻塞。 注:如果 FIFO 中有数据,则设置了阻塞标志的读操作不会因为 FIFO 中的字节数小于请求 读的字节数而阻塞,此时,读操作会返回 FIFO 中现有的数据量。 向 FIFO 中写入数据: 约定:如果一个进程为了向 FIFO 中写入数据而阻塞打开 FIFO,那么称该进程内的写操作 为设置了阻塞标志的写操作。 对于设置了阻塞标志的写操作: ? 当要写入的数据量不大于 PIPE_BUF 时,linux 将保证写入的原子性。如果此时管 道空闲缓冲区不足以容纳要写入的字节数,则进入睡眠,直到当缓冲区中能够容纳 要写入的字节数时,才开始进行一次性写操作。 ? 当要写入的数据量大于 PIPE_BUF 时,linux 将不再保证写入的原子性。FIFO 缓冲 区一有空闲区域,写进程就会试图向管道写入数据,写操作在写完所有请求写的数 据后返回。 对于没有设置阻塞标志的写操作: ? 当要写入的数据量大于 PIPE_BUF 时,linux 将不再保证写入的原子性。在写满所 有 FIFO 空闲缓冲区后,写操作返回。 ? 当要写入的数据量不大于 PIPE_BUF 时, linux 将保证写入的原子性。 如果当前 FIFO 空闲缓冲区能够容纳请求写入的字节数,写完后成功返回;如果当前 FIFO 空闲缓 冲区不能够容纳请求写入的字节数,则返回 EAGAIN 错误,提醒以后再写; 对 FIFO 读写规则的验证: 下面提供了两个对 FIFO 的读写程序, 适当调节程序中的很少地方或者程序的命令行参数就 可以对各种 FIFO 读写规则进行验证。 程序 1:写 FIFO 的程序 :
#include <sys/types.h> #include <sys/stat.h> #include <errno.h> #include <fcntl.h> #define FIFO_SERVER "/tmp/fifoserver" main(int argc,char** argv) //参数为即将写入的字节数 { int fd; char w_buf[4096*2]; int real_wnum; memset(w_buf,0,4096*2); if((mkfifo(FIFO_SERVER,O_CREAT|O_EXCL)<0)&&(errno!=EEXIST)) printf("cannot create fifoserver\n");

?

if(fd==-1) if(errno==ENXIO) printf("open error; no reading process\n");

fd=open(FIFO_SERVER,O_WRONLY|O_NONBLOCK,0); //设置非阻塞标志 //fd=open(FIFO_SERVER,O_WRONLY,0); //设置阻塞标志 real_wnum=write(fd,w_buf,2048); if(real_wnum==-1) { if(errno==EAGAIN) printf("write to fifo error; try later\n"); } else printf("real write num is %d\n",real_wnum); real_wnum=write(fd,w_buf,5000); //5000 用于测试写入字节大于 4096 时的非原子性 //real_wnum=write(fd,w_buf,4096); //4096 用于测试写入字节不大于 4096 时的原子性

if(real_wnum==-1) if(errno==EAGAIN) printf("try later\n"); }

的规则, 程序 2:与程序 1 一起测试写 FIFO 的规则,第一个命令行参数是请求从 FIFO 读出的字节 : 数
#include <sys/types.h> #include <sys/stat.h> #include <errno.h> #include <fcntl.h> #define FIFO_SERVER "/tmp/fifoserver" main(int argc,char** argv) { char r_buf[4096*2]; int int int fd; r_size; ret_size;

r_size=atoi(argv[1]); printf("requred real read bytes %d\n",r_size); memset(r_buf,0,sizeof(r_buf));

fd=open(FIFO_SERVER,O_RDONLY|O_NONBLOCK,0); //fd=open(FIFO_SERVER,O_RDONLY,0); //在此处可以把读程序编译成两个不同版本:阻塞版本及非阻塞版本 if(fd==-1) { printf("open %s for read error\n"); exit(); } while(1) {

memset(r_buf,0,sizeof(r_buf)); ret_size=read(fd,r_buf,r_size); if(ret_size==-1) if(errno==EAGAIN) printf("no data avlaible\n"); printf("real read bytes %d\n",ret_size); sleep(1); } pause(); unlink(FIFO_SERVER); }

程序应用说明: 把读程序编译成两个不同版本: ? 阻塞读版本:br ? 以及非阻塞读版本 nbr 把写程序编译成两个四个版本: ? 非阻塞且请求写的字节数大于 PIPE_BUF 版本:nbwg ? 非阻塞且请求写的字节数不大于 PIPE_BUF 版本:版本 nbw ? 阻塞且请求写的字节数大于 PIPE_BUF 版本:bwg ? 阻塞且请求写的字节数不大于 PIPE_BUF 版本:版本 bw 下面将使用 br、nbr、w 代替相应程序中的阻塞读、非阻塞读 验证阻塞写操作: 1. 当请求写入的数据量大于 PIPE_BUF 时的非原子性: o nbr 1000 o bwg 2. 当请求写入的数据量不大于 PIPE_BUF 时的原子性: o nbr 1000 o bw 验证非阻塞写操作: 1. 当请求写入的数据量大于 PIPE_BUF 时的非原子性: o nbr 1000 o nbwg

2. 请求写入的数据量不大于 PIPE_BUF 时的原子性: o nbr 1000 o nbw 不管写打开的阻塞标志是否设置,在请求写入的字节数大于 4096 时,都不保证写入的原子 性。但二者有本质区别: 对于阻塞写来说, 写操作在写满 FIFO 的空闲区域后, 会一直等待, 直到写完所有数据为止, 请求写入的数据最终都会写入 FIFO; 而非阻塞写则在写满 FIFO 的空闲区域后,就返回(实际写入的字节数),所以有些数据最终 不能够写入。 对于读操作的验证则比较简单,不再讨论。

2.5 有名管道应用实例
在验证了相应的读写规则后,应用实例似乎就没有必要了。 回页首

小结: 小结:
管道常用于两个方面:(1)在 shell 中时常会用到管道(作为输入输入的重定向),在这 种应用方式下, 管道的创建对于用户来说是透明的; (2) 用于具有亲缘关系的进程间通信, 用户自己创建管道,并完成读写操作。 FIFO 可以说是管道的推广,克服了管道无名字的限制,使得无亲缘关系的进程同样可以采 用先进先出的通信机制进行通信。 管道和 FIFO 的数据是字节流,应用程序之间必须事先确定特定的传输"协议",采用传播具 有特定意义的消息。 要灵活应用管道及 FIFO,理解它们的读写规则是关键。 附 1:kill -l 的运行结果,显示了当前系统支持的所有信号:
1) SIGHUP 5) SIGTRAP 9) SIGKILL 13) SIGPIPE 18) SIGCONT 22) SIGTTOU 26) SIGVTALRM 30) SIGPWR 34) SIGRTMIN+2 38) SIGRTMIN+6 42) SIGRTMIN+10 46) SIGRTMIN+14 50) SIGRTMAX-13 54) SIGRTMAX-9 58) SIGRTMAX-5 62) SIGRTMAX-1 2) SIGINT 6) SIGABRT 10) SIGUSR1 14) SIGALRM 19) SIGSTOP 23) SIGURG 27) SIGPROF 31) SIGSYS 35) SIGRTMIN+3 39) SIGRTMIN+7 43) SIGRTMIN+11 47) SIGRTMIN+15 51) SIGRTMAX-12 55) SIGRTMAX-8 59) SIGRTMAX-4 63) SIGRTMAX 3) SIGQUIT 7) SIGBUS 11) SIGSEGV 15) SIGTERM 20) SIGTSTP 24) SIGXCPU 28) SIGWINCH 32) SIGRTMIN 36) SIGRTMIN+4 40) SIGRTMIN+8 44) SIGRTMIN+12 48) SIGRTMAX-15 52) SIGRTMAX-11 56) SIGRTMAX-7 60) SIGRTMAX-3 4) SIGILL 8) SIGFPE 12) SIGUSR2 17) SIGCHLD 21) SIGTTIN 25) SIGXFSZ 29) SIGIO 33) SIGRTMIN+1 37) SIGRTMIN+5 41) SIGRTMIN+9 45) SIGRTMIN+13 49) SIGRTMAX-14 53) SIGRTMAX-10 57) SIGRTMAX-6 61) SIGRTMAX-2

除了在此处用来说明管道应用外,接下来的专题还要对这些信号分类讨论。 附 2:对 FIFO 打开规则的验证(主要验证写打开对读打开的依赖性)

#include <sys/types.h> #include <sys/stat.h> #include <errno.h> #include <fcntl.h> #define FIFO_SERVER "/tmp/fifoserver" int handle_client(char*); main(int argc,char** argv) { int r_rd; int w_fd; pid_t pid; if((mkfifo(FIFO_SERVER,O_CREAT|O_EXCL)<0)&&(errno!=EEXIST)) printf("cannot create fifoserver\n"); handle_client(FIFO_SERVER);

} int handle_client(char* arg) { int ret; ret=w_open(arg); switch(ret) { case 0: { printf("open %s error\n",arg); printf("no process has the fifo open for reading\n"); return -1; } case -1: { printf("something wrong with open the fifo except for ENXIO"); return -1; } case 1: { printf("open server ok\n"); return 1; } default: { printf("w_no_r return ----\n"); return 0; } }

unlink(FIFO_SERVER); } int w_open(char*arg) //0 open error for no reading

//-1 open error for other reasons //1 { if(open(arg,O_WRONLY|O_NONBLOCK,0)==-1) { if(errno==ENXIO) { return 0; } else return -1; } return 1; open ok

}


相关文章:
进程间使用管道通信pipe
进程间使用管道通信pipe_互联网_IT/计算机_专业资料。进程间使用管道通信 本节将以管道方式为例讲解进程间通信的使用方法。 管道本身是一种数据结构, 遵循先 进先...
实验八 进程通信——管道
实验八 进程通信——管道_电脑基础知识_IT/计算机_专业资料。浙江大学城市学院实验报告课程名称 实验项目名称 学生姓名 实验成绩 操作系统原理实验 实验八 进程通信—...
用管道实现进程通信
管道实现进程通信_计算机软件及应用_IT/计算机_专业资料。操作系统用管道实现进程通信 操作系统实验报告 用管道实现进程通信 1. 实验目的 (1) 了解 Windows 系统...
基于管道的进程通信实验
( 3 )创建无名管道,实现基于管道进程间数据通信, 掌握管道通信的方法及特征;并进一步理解互斥与 同步的含义 本次实验通过系统调用用 C 语言实现了父进程创建一...
进程的管道通信
进程管道通信_计算机软件及应用_IT/计算机_专业资料。计算机操作系统实验报告 计算机操作系统实验第六次实验报告 计算机操作系统实验第六次实验报告学院: 计算机科学...
实验4 进程的管道通信
实验4 一、实验目的 进程管道通信 1)加深对进程概念的理解,明确进程和程序的区别。 2)学习进程创建的过程,进一步认识进程并发执行的实质。 3)分析进程争用资源...
操作系统实验——进程的管道通信
贵州大学实验报告学院: 姓名 实验时间 实验项目名称 专业: 学号 指导教师 王道书 班级: 实验组 成绩 进程管道通信 实验目的 1、了解什么是管道 2、熟悉 UNIX/...
Linux操作系统-进程间通信—管道(父进程和两个子进程)
进程间通信—管道(父进程和两个子进程) xxx A14-322 成绩 2013 年 12 月 10 日 实验地点 一、 实验目的与要求 实验时间 实验目的:进一步熟悉 linux 中创建...
进程间通信之管道
那么再来看看通过管道进行通信的步骤: 》父进程创建管道,得到两个文件描述符指向管道的两端 》利用 fork 函数创建出子进程,则子进程也得到两个文件描述符指向同一...
实验9 进程间管道通信实验
试验9 进程间管道通信实验学 号: 6100412196 学生姓名: 李亚军 专业班级: 卓越计科 121 班 1.实验目的 通过编写有名管道多路通信实验,读者可进一步掌握管道的创建...
更多相关标签:
进程间通信 管道 | 进程的管道通信 | 进程通信 管道 | 进程的管道通信实验 | 基于管道的进程间通信 | 匿名管道多进程通信 | 父子进程管道通信 | linux进程间通信 管道 |