进程间的通信

本文详细介绍了Linux系统中进程间通信的两种方式:匿名管道和命名管道。首先,概述了进程间通信的目的和分类,接着详细讲解了匿名管道的概念、使用步骤、读写规则、特点及多进程派发任务的实现。然后,介绍了命名管道,包括其概念、打开规则、用命名管道实现服务端和客户端通信以及进程控制,以及与匿名管道的区别。最后提到了System V进程间通信的共享内存机制,阐述了共享内存的创建、释放、关联、去关联、使用示例及其与管道的对比。
摘要由CSDN通过智能技术生成

目录

一.进程间通信的介绍

1.1通信的目的

1.2进程间通信的分类

二.匿名管道

2.1概念

2.1.2使用步骤

2.2管道读写规则

2.3特点

2.4多进程派发任务的实现

2.5管道大小

三.命名管道

3.1概念

3.2命名管道的打开规则

3.3命名管道演示

3.3.1用命名管道实现serve&client通信 

 3.3.2用命名管道实现进程控制

3.4命名管道和匿名管道的区别

3.5命令行中的管道

四.system V进程间通信

4.1system V共享内存

4.1.1共享内存的建立与释放

4.1.2创建

 4.1.3释放

4.1.4关联

 4.1.5去关联

4.1.6用共享内存实现serve&client通信

 4.1.7共享内存与管道进行对比

五.消息队列

六.System V信号量


一.进程间通信的介绍

概念:进程间通信简称IPC(Interprocess communication),进程间通信就是在不同进程之间传播或交换信息。

1.1通信的目的

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

本质就是让不同的进程可以看到同一份资源。

每个进程都是独立的,各个进程之间若想实现通信,一定要借助第三方资源,这些进程就可以通过向这个第三方资源写入或是读取数据,进而实现进程之间的通信,这个第三方资源实际上就是操作系统提供的一段内存区域。

b740fa5b5ac240a99478ab4490e7f181.png

1.2进程间通信的分类

管道

  • 匿名管道
  • 命名管道

System V IPC

  • System V 消息队列
  • System V 共享内存
  • System V 信号量

POSIX IPC

  • 消息队列
  • 共享内存
  • 信号量
  • 互斥量
  • 条件变量
  • 读写锁

二.匿名管道

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

183ed0dceaeb443e94b055f568affb56.png

2.1概念

匿名管道用于进程间通信,但仅限于本地父子进程之间的通信。使用匿名管道通信,可以让父子进程看到同一份资源,父子进程可以对其进行读写操作,从而实现通信。

如图:

5d59616c9628458aaec82742c08683f2.png

 补充:

1.这里父子进程看到的同一份资源是由操作系统维护的,父子进程对其进行读写操作时不会发生写时拷贝。

2.管道虽然用的是文件的方案,但操作系统不会把进程进行通信的数据刷新到磁盘当中,因为这样做有IO参与会降低效率。也就是说,这种文件是一批不会把数据写到磁盘当中的文件,换句话说,磁盘文件和内存文件不一定是一一对应的,有些文件只会在内存当中存在,而不会在磁盘当中存在。

创建匿名管道的函数:

int pipe(int pipefd[2]);

解释:pipe函数的参数是一个输出型参数,数组pipefd用于返回两个指向管道读端和写端的文件描述符。函数调用成功返回0,失败返回-1。

数组元素 含义
pipefd[0] 管道读端的文件描述符
pipefd[1] 管道写端的文件描述符

2.1.2使用步骤

创建匿名管道实现父子进程间通信的过程中,需要pipe函数和fork函数搭配使用.

例如:

1.先由父进程调用pipe函数,创建管道。

2.父进程在创建子进程。

3.父进程关闭写端,子进程关闭读端。

也可站在文件描述的角度来看待:

c698198d6ef0410cbe53a7e4d0bf9b30.png

755e488b7b1a4a10a498a36afddae27d.png

c87a9caf65bd49a5954c1a74f723cadb.png

 用代码进行演示:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
int main()
{
	int fd[2] = { 0 };
	if (pipe(fd) < 0){ //使用pipe创建匿名管道
		perror("pipe");
		return 1;
	}
	pid_t id = fork(); //使用fork创建子进程
	if (id == 0)
	{
	close(fd[0]); //子进程关闭读端
    char arr[20]="hello world";
		for(int i=0;i<5;i++)
		{	write(fd[1], arr, strlen(arr));	//子进程向管道写入数据
			sleep(1);
		}
		close(fd[1]); //子进程写入完毕,关闭文件
		exit(0);
	}
	close(fd[1]); //父进程关闭写端
	char buff[64];
	while (true)
	{
		ssize_t s = read(fd[0], buff, sizeof(buff
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值