Linux进程间通信

下面简单介绍有三种进程间通信的方式 : 1. 匿名管道–pipe; 2.命名管道–fifo; 3.内存映射–mmap;

管道位于内核中, 进程共享内核区域

1. pipe 管道

	#include <unistd.h>	
	int pipe(int pipefd[2]);
	
	#define _GNU_SOURCE             /* See feature_test_macros(7) */
	#include <fcntl.h>              /* Obtain O_* constant definitions */
	#include <unistd.h>	
	int pipe2(int pipefd[2], int flags);
	如果成功,返回0,否则返回-1并且设置errno, pipefd[2]是传出参数
	
	管道作用于有血缘关系的进程之间, 通过fork来传递
	调用pipe函数时在内核中开辟一块缓冲区(称为管道)用于通信,它有一个读端有一个写端, 然后
	通过pipefd参数传出给用户程序两个文件描述符, pipefd[0]指向管道的读端, pipefd[1]指向管道的
	写端,所以管道在用户程序看起来就好像一个打开的文件,通过read(pipefd[0])或者write(pipefd[1])
		1.父进程调用pipe开辟管道, 得到两文件描述符指向管道的两端
		2.父进程调用fork创建子进程, 那么子进程也有两个文件描述符指向同一管道
		3.父进程关闭管道读端, 子进程关闭管道写端, 父进程可以往管道里写,子进程可以从管道里读,管道是用
		环形队列实现的,数据从写端流入从读端流出,这样就实现了进程间通信
	**管道使用的注意事项:**
		1.如果写端关闭, 读端读管道内容至读完, 再次读取时,返回0, 相当于读到EOF读端关闭
		2.如果写端没关闭, 但是写端暂时无数据, 读端读完管道里的数据时, 再次读, 读端会发生阻塞
		3.如果读端关闭, 写端写入数据到管道, 会产生SIGPIPE信号, 导致写进程终止
		4.如果读端没有从管道读取数据, 写端一直往管道写入数据, 直到写满, 当写端再次写入时,写端会发生阻塞
	fpathconf(fd[0], _PC_PIPE_BUF)
	可以测试管道缓冲区大小, fcntl函数可以设置管道非阻塞

2.fifo

	命令 : mkfifo fifoname		创建一个名为fifoname的管道文件
	fifo有名管道, 主要作用于无血缘关系的进程间通信
	
	#include <sys/types.h>
	#include <sys/stat.h>
	int mkfifo(const char *pathname, mode_t mode);
	成功返回0, 失败返回-1 并设置errno

3.mmap/munmap 内存共享映射/解除内存共享映射

	mmap可以把磁盘文件的一部分直接映射到内存,这样文件中的位置直接就有对应的地址, 对文件的读写可以直接用指针来做而不需要read/write函数
	#include <sys/mman.h>
	void *mmap(void *addr, size_t length, int prot, int flags,
				int fd, off_t offset);
			addr : 指定映射的位置,通常传入NULL
			length : 申请内存的长度
			prot : 设置页面属性 (页面 : Pages, 4096字节, 分配内存时以 页 为单位分配)
				PROT_EXEC				用户申请的页面是否有执行权限, 共享库通过mmap映射到内存当中,并给这块内存分配exec执行权限
				PROT_READ				用户申请的页面是否有读权限 
				PROT_WRITE				用户申请的页面是否有写权限
				PROT_NONE				用户申请的页面不允许被访问
			flags : 
				MAP_SHARED			当内存地址中的内容发生修改,磁盘文件也同步修改,反之亦然
				MAP_PRIVATE			当内存地址中的内容发生修改,磁盘文件没有变化,反之亦然
			fd : 文件描述符(
			offset : 偏移量, 偏移量必须是4096的整数倍(按 页 偏移)
	int munmap(void *addr, size_t length);
	mmap如果成功,mmap()返回一个指向映射区域的指针,如果失败返回MAP_FAILED(即(void *) -1), 并设置errno
	munmap如果成功返回0, 失败返回-1, 并设置errno
	注意:
		用于进程间通信时一般设为结构体
		用于通信的文件, 根据需求设置为临时文件或非临时文件
		报总线错误时, 优先查看是否有大小为0的共享文件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值