管道(pipe):管道可用于具有亲缘关系的进程间的通信,是一种半双工的方式,数据只能单向流动,允许一个进程和另一个与它有共同祖先的进程之间进行通信。
PIPE模块程序一
下面模块代码是在主函数中创将一个进程,在子进程中往管道中写数据,在父进程中读取数据,也就是一对一的读写操作。
/*============================================================================= # FileName: pipe1.c # Desc: an example of pipe communication application # Author: Licaibiao # Version: # LastChange: 2017-01-09 # History: =============================================================================*/ #include <sys/wait.h> #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> int main( int argc, char *argv[]) { pid_t pid; int fd[ 2]; int read_count = 0; int i; char read_buffer[ 10] = { 0}; char write_buffer[ 10] = { 0}; /*create pipe*/ if (pipe(fd) < 0) { printf( "Create pipe failed\n"); return -1; } /*create process*/ if ((pid = fork()) < 0) { printf( "Fork failed\n"); return -1; } /* child */ if (pid == 0) { printf( "[child]Close read endpoint...\n"); /* close read */ close(fd[ 0]); for(i= 0;i< 10;i++) { write_buffer[i]=i; } write(fd[ 1],write_buffer,i); } /*father*/ else { printf( "[parent]Close write endpoint...\n"); /* close write */ close(fd[ 1]); read_count = read(fd[ 0], read_buffer, 10); printf( "father process read data\n"); for(i= 0; i<read_count; i++) { printf( "read_buffer[%d] = %d\n",i,read_buffer[i]); } } } 程序执行结果: root@ubuntu:/home/share/pipe # gcc pipe1.c -o test root@ubuntu:/home/share/pipe # ./test [parent]Close write endpoint... [child]Close read endpoint... father process read data read_buffer[ 0] = 0 read_buffer[ 1] = 1 read_buffer[ 2] = 2 read_buffer[ 3] = 3 read_buffer[ 4] = 4 read_buffer[ 5] = 5 read_buffer[ 6] = 6 read_buffer[ 7] = 7 read_buffer[ 8] = 8 read_buffer[ 9] = 9 PIPE模块程序二下面的程序是在主进程中创建了三个子进程,在子进程中写入数据,在父进程中读出数据,这里使用的是多进程写入,因此需要对文件进程加锁,这里使用的了lockf函数。
/*============================================================================= # FileName: pipe2.c # Desc: three process write piep and father process read data # Author: Licaibiao # Version: # LastChange: 2017-01-09 # History: =============================================================================*/ #include <sys/wait.h> #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <unistd.h> #include <signal.h> #include <stdio.h> int main( void) { int fd[ 2]; int i; int pid[ 3]={ 1, 1, 1}; char outpipe[ 100],inpipe[ 100]; pipe(fd); /* create three process */ for(i= 0;i< 3;i++) { pid[i]=fork( ); if(pid[i]== 0) break; } if(pid[ 0]== 0) { lockf(fd[ 1],F_LOCK, 0); sprintf(outpipe, "child 1 process is sending message!"); write(fd[ 1],outpipe, 50); sleep( 5); lockf(fd[ 1],F_ULOCK, 0); exit( 0); } if(pid[ 1]== 0) { lockf(fd[ 1],F_LOCK, 0); sprintf(outpipe, "child 2 process is sending message!"); write(fd[ 1],outpipe, 50); sleep( 5); lockf(fd[ 1],F_ULOCK, 0); exit( 0); } if(pid[ 2]== 0) { lockf(fd[ 1],F_LOCK, 0); sprintf(outpipe, "child 3 process is sending message!"); write(fd[ 1],outpipe, 50); sleep( 5); lockf(fd[ 1],F_ULOCK, 0); exit( 0); } wait( 0); read(fd[ 0],inpipe, 50); printf( "%s\n",inpipe); read(fd[ 0],inpipe, 50); printf( "%s\n",inpipe); read(fd[ 0],inpipe, 50); printf( "%s\n",inpipe); return 0; } 这里创建了三个进程,进程执行的顺序是不确定的,当pipe被锁定的时候,其他的请求操作这个文件的进程将被阻塞,直到pipe被解除锁定之后,其他的进程之间进行竞争决定谁先谁后执行。多次运行结果下: root@ubuntu:/home/share/pipe # gcc pipe2.c -o test root@ubuntu:/home/share/pipe # ./test child 3 process is sending message! child 2 process is sending message! child 1 process is sending message! root@ubuntu:/home/share/pipe # ./test child 3 process is sending message! child 2 process is sending message! child 1 process is sending message! root@ubuntu:/home/share/pipe # ./test child 3 process is sending message! child 2 process is sending message! child 1 process is sending message! root@ubuntu:/home/share/pipe # ./test child 2 process is sending message! child 3 process is sending message! child 1 process is sending message! root@ubuntu:/home/share/pipe # ./test child 3 process is sending message! child 2 process is sending message! child 1 process is sending message! root@ubuntu:/home/share/pipe # ./test child 3 process is sending message! child 2 process is sending message! child 1 process is sending message! root@ubuntu:/home/share/pipe # ./test child 3 process is sending message! child 2 process is sending message! child 1 process is sending message! root@ubuntu:/home/share/pipe # ./test child 3 process is sending message! child 2 process is sending message! child 1 process is sending message! root@ubuntu:/home/share/pipe # ./test child 1 process is sending message! child 3 process is sending message! child 2 process is sending message! root@ubuntu:/home/share/pipe # 如果要固定执行先后顺序,可以把子进程一个一个的分开来创建,每创建一个子进程就请求操作pipe,最后在父进中读取就可以了。PIPE模块程序三
下面的程序是两个进程写入,两个进程读取,在pipe中写入的数据,其他的进程再读取的时候,将读取不到数据。程序代码如下:
/*============================================================================= # FileName: pipe3.c # Desc: two process write into pipe and two process read from pipe # Author: Licaibiao # Version: # LastChange: 2017-01-09 # History: =============================================================================*/ #include <sys/wait.h> #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <unistd.h> #include <signal.h> #include <stdio.h> int main( void) { int fd[ 2], i; int pid[ 3] = { 1, 1, 1}; char outpipe[ 100],inpipe[ 100]; pipe(fd); for(i= 0;i< 3;i++) { pid[i]=fork( ); if(pid[i]== 0) break; } if(pid[ 0]== 0) { lockf(fd[ 1],F_LOCK, 0); sprintf(outpipe, "child 1 process is sending message!"); write(fd[ 1],outpipe, 50); sleep( 5); lockf(fd[ 1],F_ULOCK, 0); exit( 0); } if(pid[ 1]== 0) { lockf(fd[ 1],F_LOCK, 0); sprintf(outpipe, "child 2 process is sending message!"); write(fd[ 1],outpipe, 50); sleep( 5); lockf(fd[ 1],F_ULOCK, 0); exit( 0); } if(pid[ 2]== 0) { lockf(fd[ 0],F_LOCK, 0); read(fd[ 0],inpipe, 50); printf( "Child 3 read:\n%s\n",inpipe); lockf(fd[ 0],F_ULOCK, 0); exit( 0); } wait( 0); read(fd[ 0],inpipe, 50); printf( "Parent read:\n%s\n",inpipe); exit( 0); } 执行结果如下: root@ubuntu:/home/share/pipe # vim pipe3.c root@ubuntu:/home/share/pipe # gcc pipe3.c -o test root@ubuntu:/home/share/pipe # ./test Child 3 read: child 2 process is sending message! Parent read: child 1 process is sending message! root@ubuntu:/home/share/pipe # ./test Child 3 read: child 2 process is sending message! Parent read: child 1 process is sending message! root@ubuntu:/home/share/pipe # ./test Child 3 read: child 2 process is sending message! Parent read: child 1 process is sending message! root@ubuntu:/home/share/pipe # ./test Child 3 read: child 2 process is sending message! Parent read: child 1 process is sending message!