linux 进程间通信管道

管道通信

管道是进程间通讯的一种实现。管道分为两种,有名管道和无名管道。无名管道主要是用于具有父子或兄弟关系的进程间通讯。使用pipe()创建无名管道。
#include <unistd.h>
int pipe(int pipefd[2]);
功能:创建一个单工的无名管道
参数:pipefd指定一个有两个整型元素的数组名字。
pipefd[0] 指向管道读端 pipefd[1] 指向管道的写端
返回值:成功 返回0 错误 返回-1 errno被设置为相应的错误值

使用无名管道实现进程间通讯的分析

父进程调用pipe()在内核空间创建无名管道,返回指向管道两端的文件描述符fd[2].fd[0]中存放管道的读端,fd[1]指向管道的写端。
在这里插入图片描述
父进程调用fork(),子进程继承父进程的文件描述符
在这里插入图片描述

使用无名管道实现进程间通讯的实例

使用无名管道实现父子进程间的通讯。父进程负责向管道写入数据;子进程负责从管道里读取数据,并将读取到的数据输出到显示屏。

父进程负责向管道写入数据的任务:
1.创建管道,返回两个文件描述符,分别用于管道的读和写端
2.创建子进程。子进程继承父进程的文件描述符。
3.关闭管道的读端
4.向管道写入数据。如果管道满,阻塞等待。
5.关闭管道的写端
6.阻塞等待子进程的结束,回收子进程的资源

子进程负责从管道读取数据的任务:
1.关闭管道的写段
2.从管道的读端读取数据
3.将读取数据写入到显示器
4.关闭管道的读端
5.终止子进程

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>

int main(){
	int fd[2];
	char buf[128];
	char *msg="this is a test...";
	//创建管道 fd{0} 指向管道读端 	fd[1]指向管道写端
	int pp =pipe(fd);
	if(pp ==-1)printf("pipe create error");
	
	//创建子进程
	pid_t pid =fork();
	if(pid == -1) printf("fork create error");
	if(pid == 0){
		close(fd[1]); //关闭写通道
		int r=read(fd[0],buf,128);
		write(1,buf,r);
		close(fd[0]);
		exit(0);
	}
	else{
		close(fd[0]);	//关闭读通道
		write(fd[1],msg,strlen(msg));
		close(fd[1]);	//关闭写端
		wait(NULL);
	}
	return 0;
}

有名管道通信

有名管道是一种类型的文件。这种文件的内容始终为0,只是起到进程间通讯的桥梁作用。
int mkfifo(const char *pathname,mode_t mode);
功能:创建一个有名管道文件
参数:pathname指定要创建的文件名字
mode:指定管道文件的权限
返回值:成功 返回0 错误 返回-1 errno被设置为相应的错误值
注解:一旦创建完管道类型的文件,就可以向使用普通文件一样使用这个文件实现进行进程的通讯。读写均阻塞。需要两个进程配合使用。
案例说明:
程序fifo.c 负责创建有名管道类型文件
程序pa.c 负责向有名管道文件写入数据
程序pb.c 负责从管道中读取数据。将读取出来的消息输出到显示器

fifo.c

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>

int main(int argc,char *argv[])
{
        int fifo;
        fifo=mkfifo(argv[1],0644);
        if(fifo==-1)
        {
                printf("create error fifo");
        }
        printf("create success %s\n",argv[1]);
        return 0;
}

pa.c

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
int main(int argc,char *argv[])
{
        char *msg="this is a test";
        int fd = open(argv[1],O_WRONLY);
        if(fd == -1)printf("open file error");
        int h=write(fd,msg,strlen(msg));
        if(h<0)
        {
                printf("write error");
        }
        else
        {
                printf("write %d bytes",h);
        }
        close(fd);
        return 0;
}

pb.c

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
int main(int argc,char *argv[])
{
        char buf[128];
        int fd = open(argv[1],O_RDONLY);
        if(fd == -1)printf("open file error");
        int h=read(fd,buf,128);
        if(h<0)
        {
                printf("read error");
        }
        else
        {
                printf("read %d bytes\n",h);
                printf("%s",buf);
        }
        close(fd);
        return 0;
}

测试结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值