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

    管道(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!

由于各种原因,后续文章内容将更新到公众号,本平台将不再做更新。

CSDN上相关文章的测试工程代码,也统一放到了公众号上,可以免费免积分下载

可以通过主页上的二维码,也可以通过搜索微信公众号 liwen01 进入公众号

liwen01   2022.08.21


 

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

li_wen01

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值