管道(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
下面的程序是在主进程中创建了三个子进程,在子进程中写入数据,在父进程中读出数据,这里使用的是多进程写入,因此需要对文件进程加锁,这里使用的了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!