什么是管道?数组
管道是单向的、先进先出的,它把一个进程的输出和另外一个进程的输入链接在一块儿。一个进程(写进程)在管道的尾部写入数据,另外一个进程(读进程)从管道的头部读出数据。函数
管道的分类this
管道包括无名管道和命名管道两种,前者用于父进程和子进程间的通讯,后者可用于运行于同一系统或者跨系统中的任意两个进程间的通讯。spa
无名管道由pipe( )函数建立:int pipe(int filedis[2]);操作系统
当一个管道被建立时,它会建立两个文件描述符:filedis[0]用于读管道,filedis[1]用于写管道。管道通讯示意图以下图1所示:.net
管道通讯示意图1指针
文件描述符: 内核(kernel)利用文件描述符(file descriptor)来访问文件。文件描述符是非负整数。打开现存文件或新建文件时,内核会返回一个文件描述符。读写文件也须要使用文件描述符来指定待读写的文件。blog
管道关闭:关闭管道只是将两个文件描述符关闭便可,可使用普通的close函数逐个关闭。继承
无名管道读写:管道用于不一样进程间通讯。一般先建立一个管道,再经过fork函数建立一个子进程,该子进程会继承父进程建立的管道。注意事项:必须在系统调用fork()前调用pipe(),不然子进程将不会继承文件描述符。不然,会建立两个管道,由于父子进程共享同一段代码段,都会各自调用pipe(),即创建两个管道,出现异常错误。无名管道读写过程如图2所示:进程
管道通讯示意图2
管道的定义:int pipe(int filedes[2]);
管道建立参数:int filedes[2]----一个数组
管道建立方式:pipe(fieldes)----建立一个管道,此管道函数的执行结果是建立管道的同时,也建立了一个管道读取端,一个管道写入端,读取端赋予参数fields(0),写入端赋予参数fields(1).
管道建立的返回值-----1或者0,0表示建立成功,1表示建立失败。
管道建立失败的缘由保存在errno中,包括如下几种:
EMFILE 进程已用完文件描述词最大量
ENFILE 系统已无文件描述词可用
EFAULT 参数 filedes 数组地址不合法。
无名管道经典实例
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
int main( void )
{
int filedes[2];
char buf[80];
pid_t pid;
pipe( filedes );
if ( (pid=fork()) > 0 )
{
printf( "This is in the father process,here write a string to the pipe.\n" );
char s[] = "Hello world , this is write by pipe.\n";
write( filedes[1], s, sizeof(s) );
close( filedes[0] );
close( filedes[1] );
}
else
{
printf( "This is in the child process,here read a string from the pipe.\n" );
read( filedes[0], buf, sizeof(buf) );
printf( "%s\n", buf );
close( filedes[0] );
close( filedes[1] );
}
waitpid( pid, NULL, 0 );
return 0;
}
[root@localhost src]# gcc pipe.c
[root@localhost src]# ./a.out
This is in the child process,here read a string from the pipe.
This is in the father process,here write a string to the pipe.
Hello world , this is write by pipe.
fork以后,操做系统会复制一个与父进程彻底相同的子进程,虽然说是父子关系,可是在操做系统 看来,他们更像兄弟关系,这2个进程共享代码空间,可是数据空间是互相独立的,子进程数据空间中的内容是父进程的完整拷贝,指令指针也彻底相同,但只有一 点不一样,若是fork成功,子进程中fork的返回值是0,父进程中fork的返回值是子进程的进程号,若是fork不成功,父进程会返回错误。
能够这样想象,2个进程一直同时运行,并且步调一致,在fork以后,他们分别做不一样的工做,也就是分岔了。这也是fork为何叫fork的缘由。
至于那一个最早运行,可能与操做系统有关,并且这个问题在实际应用中并不重要,若是须要父子进程协同,能够经过原语的办法解决。
#include ;
#include ;
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
main (){
pid_t pid;
pid=fork();
if (pid < 0)
printf("error in fork!");
else if (pid == 0)
printf("i am the child process, my process id is %d\n",getpid());
else
printf("i am the parent process, my process id is %d\n",getpid());
}
结果是
[root@localhost c]# ./a.out
i am the child process, my process id is 4286
i am the parent process, my process id is 4285
也能够参考一篇文章:http://blog.csdn.net/wc7620awjh/article/details/7709581