您的位置:首页 > 运维架构 > Linux

Linux进程间通信——pipe应用实例

2017-01-09 19:25 381 查看
    管道(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!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Linux pipe IPC