进程通信1-管道通信

管道通信顾名思义就是创建一根管道,这个管道有读写两端
管道有两种:匿名管道和命名管道

1.匿名管道

匿名管道只能父子进程间通信,如图,他会创建两个读写端分别对应父子进程,只要父子进程分别关闭读,或者写端,就可以一个进程发送信息给另一个进程。
规则:
1.如果没有数据可读,或者管道满的时候,read和write调用都会阻塞
2.如果有读写端被关闭,调用返回0
3.写入的数据量小于PIPE_BUF时,linux将保证写.入的原子性
写入的数据量大于PIPE_BUF时,linux将不再保证写入的原子性
在这里插入图片描述
代码实现,详细注释:

#include<stdio.h>
#include<unistd.h>
#include<memory.h>
#include<stdlib.h>
int main()
{
    
    
	char buf[100] = "This is message!\n";
	int fds[2];
	if (pipe(fds) == -1) //创建匿名管道
		perror("pipe"), exit(1);
	pid_t pid = fork();//创建子进程
	if (pid == 0)
	{
    
    
	//关闭子进程管道读描述符
		close(fds[0]); 
		//子进程写消息进管道
		if (write(fds[1], buf, strlen(buf)+1) == -1) 
		{
    
    
			perror("write");
				exit(1);
		}
		printf("i'm son,write in buf is:%s", buf);
		close(fds[1]); 

	}
	else
	{
    
    
		memset(buf, 0, sizeof(buf));
		//关闭父进程管道写描述符
		close(fds[1]); 
		//父进程从管道读内容,如果此时子进程还没被创建出来,
		//read会堵塞,所以一定会读到数据
		if (read(fds[0], buf, sizeof(buf)) == -1) 
			perror("read"), exit(1);
		printf("i'm father,read from buf is:%s", buf);
		close(fds[0]);

	}
	return 0;

}      

代码执行如图
在这里插入图片描述

2.命名管道

理解了匿名管道,命名的就好理解了,命名的管道就是有一个进程会创建出来这个管道,然后其他进程也可以通过这个管道的名字一起来通信
这个命名管道经过测试,就是一个跟文件一样的东西,如果编译的话,会在当前目录下生成,,所以其他进程打开这个管道需要加上路径,不然会打不开

代码实现:
创建端.cpp

#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>

int main()
{
    
    
	mkfifo("mypipe", 0664);
	int outfd = open("mypipe", O_WRONLY);
	if (outfd == -1)
		perror("open "), exit(1);
	char buf[100] = {
    
    };
	int n = sizeof(buf);
	while (fgets(buf, n, stdin))
	{
    
    
		write(outfd, buf, strlen(buf));
		memset(buf, 0, n);
	}
	close(outfd);
	return 0;
}

加入端.cpp

#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>
int main()
{
    
    
	//注意这里打开的路径是之前创建的
	int infd = open("mypipe", O_RDONLY);
	if (infd == -1)
		perror("open mypipe"), exit(1);
	char buf[10] = {
    
    };
	int n = 0;
	while ((n = read(infd, buf, sizeof(buf))) > 0)
	{
    
    
		if (strlen(buf) > 0)
		{
    
    
			printf("recv from pipe :%s\n", buf);
		}
		memset(buf, 0, sizeof(buf));
	}
	close(infd);
	unlink("mypipe"); //删除管道
	return 0;
}

在这里插入图片描述
在这里插入图片描述

所以管道通信局限性还是很大,不够好

Guess you like

Origin blog.csdn.net/qq_40861091/article/details/102174992