Linux进程通信

目录

一、进程间通信

1.通信的技术背景

2.进程间通信的目的

3.为什么要有通信

4.进程间通信的本质

5.进程间通信的方式

二.管道

匿名管道

管道总结

管道读写规则

命名管道

创建命名管道

匿名管道与命名管道的区别 

3.共享内存

共享内存的题 

ipcrm 删除进程间通信资源


一、进程间通信

1.通信的技术背景

每个进程都有自己独立的内核数据结构,具有独立性的进程之间如果想要通信的话,成本一定是不低的。

2.进程间通信的目的

a.数据传输:一个进程需要将它的数据发送给另一个进程
b.资源共享:多个进程之间共享同样的资源。
c.通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)。
d.进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变。比如在gdb调试时,用的就是gdb进程控制被调试的进程。

3.为什么要有通信

有时候单独进程的工作是无法满足需求的,所以我们是需要多进程协同完成某种业务内容的。
例如:cat file | grep ‘hello’

4.进程间通信的本质

是为了让不同进程看到同一份资源

5.进程间通信的方式

典型进程间通信方式:管道,共享内存,消息队列,信号量。 除此之外还有网络通信,以及文件等多种方式 

二.管道

管道是Unix中最古老的进程间通信的形式。 
我们把从一个进程连接到另一个进程的一个数据流称为一个“管道

管道是半双工通信,是可以选择方向的单向通信

管道本质是内核中的一块缓冲区,多个进程通过访问同一块缓冲区实现通信。
多个进程只要能够访问同一管道就可以实现通信,不限于读写个数
管道在缓冲区写满后会写阻塞,跟磁盘空间并无关系

匿名管道

匿名管道只能用来进行父子进程之间的通信

匿名管道需要在创建子进程之前创建,因为只有这样才能复制到管道的操作句柄,与具有亲缘关系的进程实现访问同一个管道通信

#include <unistd.h>
功能:创建一无名管道
原型
int pipe(int fd[2]);
参数
fd:文件描述符数组,其中fd[0]表示读端, fd[1]表示写端
返回值:成功返回0,失败返回错误代码

通过匿名管道写一个代码

#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<string.h>
int main()
{
	int fd[2];//定义文件描述符数组
	int ret=pipe(fd);//创建管道
	if(ret==-1)
	{
		perror("pipe");
		exit(1);	
	}
	pid_t pid=fork();//创建子进程
	if(pid>0)//父进程 写
	{
		close(fd[0]);//关闭读端
		const char *p= "hello\n";
		write(fd[1],p,strlen(p)+1);//写数据
		close(fd[1]);
		wait(NULL);
	}else if(pid==0)//子进程 读
	{
		close(fd[1]);   关闭写端
		char buf[64]={0};
		ret=read(fd[0],buf,sizeof(buf));
		close(fd[0]);
		write(STDOUT_FILENO,buf,ret);
	}
	return 0;
	
}

管道总结

管道读写规则

若管道所有写段关闭,则从管道中读取完所有数据后,继续read会返回0,不再阻塞;若所有读端关闭,则继续write写入会触发异常导致进程退出
当要写入的数据量不大于PIPE_BUF时,linux将保证写入的原子性。
当要写入的数据量大于PIPE_BUF时,linux将不再保证写入的原子性。

命名管道

如果我们想在不相关的进程之间交换数据,可以使用FIFO文件来做这项工作,称为命名管道。
命名管道是一种特殊类型的文件

创建命名管道

命名管道可以从命令行上创建,命令行方法是使用下面这个命令:
mkfifo   filename

匿名管道与命名管道的区别 

匿名管道由pipe函数创建并打开。
命名管道由mkfifo函数创建,打开用open
FIFO(命名管道)与pipe(匿名管道)之间唯一的区别在它们创建与打开的方式不同,一但这些工作完 成之后,它们具有相同的语义。

3.共享内存

共享内存区是最快的 IPC 形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到 内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据

 

 1.进程间通讯的方式中哪种的访问速度最快?

共享内存的题 

共享内存的本质就是开辟一块物理内存,让多个进程映射同一块物理内存到自己的地址空间进行访问,实现数据共享的

共享内存的删除操作并非直接删除,而是拒绝后续映射,只有在当前映射链接数为0时,表示没有进程访问了,才会真正被删除

共享内存生命周期随内核,只要不删除,就一直存在于内核中,除非重启系统(当然这里指的是非手动操作,可以手动删除)

ipcrm 删除进程间通信资源

  -m 针对共享内存的操作

  -q 针对消息队列的操作

  -s 针对信号量的操作

  -a 针对所有资源的操作

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值