-
2018-08-10 10:24:06
进程间的八种通信方式----共享内存是最快的 IPC 方式
1.无名管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
2.高级管道(popen):将另一个程序当做一个新的进程在当前程序进程中启动,则它算是当前程序的子进程,这种方式我们成为高级管道方式。
3.有名管道 (named pipe) : 有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
4.消息队列( message queue ) : 消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
5.信号量( semophore ) : 信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
6.信号 ( sinal ) : 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
7.共享内存( shared memory ) :共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。
8.套接字( socket ) : 套解字也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器间的进程通信。更多相关内容 -
分布式共享内存两种实现方式
2019-08-07 16:54:48这里,我们介绍两种分布式共享内存,一种是分布式共享内存,另外一种是naive分布式共享内存 简单的分布式共享内存 所有的进程去访问一个共享内存,这个共享内存是虚拟的,他可能分布在不同的物理机上,其实可以...分布式共享内存
这里,我们介绍两种分布式共享内存,一种是分布式共享内存,另外一种是naive分布式共享内存简单的分布式共享内存
所有的进程去访问一个共享内存,这个共享内存是虚拟的,他可能分布在不同的物理机上,其实可以理解为一种抽象,他整合了所有的存储资源,然后所有的调度、分配、读写都对程序员是隐藏的,他提供给程序员的就是一个虚拟的内存块(或者内存管理平台),程序员就可以向操作一块磁盘一样去在上进行编程或者其他的行为,这有点类似于云计算的思想。naive分布式共享内存
每一个机器都有一个存储内容的本地副本,读取操作我们可以从本地内存进行读取,写入操作我们可以先在本地下写入之后,再通过广播向其他的内存块发送update消息。我们可以看到naive方式的共享内存速度是非常快的,因为他不需要去跟其他的用户进行交流,省去了通信的消耗。
-
以通信方式共享内存,不要以共享内存方式通信
2022-04-16 10:44:01往小了说,golang建议使用channel来共享信息而不是使用共享内存,这是一种优雅的方式,避免了数据同步带来的繁琐和低效。 往大了说,本质上还是让资源去调度请求,而不是让请求去调度资源。 资源就那么多,所有请求...题目是一句golang编程箴言,对它的理解可大可小。
往小了说,golang建议使用channel来共享信息而不是使用共享内存,这是一种优雅的方式,避免了数据同步带来的繁琐和低效。
往大了说,本质上还是让资源去调度请求,而不是让请求去调度资源。
资源就那么多,所有请求有序使用资源的方式就是通信的方式,反过来,为每个请求虚拟出它独占资源的假象,那就是共享的方式。两种截然不同的方式,差异体现在仲裁成本,这个成本决定了它们承载并发的能力。
再看下面这篇文章:
https://zhuanlan.zhihu.com/p/492863461一个一个说。
电路交换 vs 分组交换
- 电路交换试图占有整条电路(其实是最后一公里),若不成功,必须等到成功。
- 分组交换将长信息分割成若干小数据包,小数据包统计复用链路。
批处理系统 vs 分时系统
- 批处理用户一旦使用系统,则会独占系统到任务完成,其它用户等待。
- 分时系统将时间分片,多用户被调度复用时间片。
CSMA/CD vs 交换式以太网
- CSMA/CD主机试图独占总线发送数据包,若不成功便退避直到成功。
- 交换式以太网数据包在交换机有序排队,复用buffer。
Apache vs Nginx
- Apache为每一个请求生成一个task,该task一旦获得CPU,其它task将等待。
- Nginx采用异步模型,所有请求分时复用固定数量task的CPU时间。
共享内存 vs erlang/go channel
- 共享内存对写写以及读写是互斥,每次只允许一个操作,其它不得不等待,重试。
- erlang/go channel将内容拆解为事务消息,依靠消息的有序传递共享信息。
…
我们来看上述两两比较的共性。
可将上述所有的二者抽象为争抢模式和有序模式:
- 对于争抢模式,本质上需要对冲突进行仲裁。
- 对于有序模式,本质上需要对并发进行调度。
所谓对冲突进行仲裁,意思就是发生冲突后怎么办。无论是退避重试,还是等待,此期间均是什么都做不了,且仲裁本身需要昂贵的成本。
并发调度就会好太多,有序化便无冲突,也就没有仲裁成本了,没有了仲裁,也就无需重试,等待,便可以干别的了,处理完全异步化。
以上述列举的顺序,分别是:电路交换 vs 分组交换
- 电路交换一旦占线,你需要自己不断重试。
- 分组交换你只管发数据包,交换节点会自动调度这些数据包到达目的地后重组。
批处理系统 vs 分时系统
- 批处理系统一旦系统被占,你就要排队等待或者待会儿再来。
- 分时系统你只需要下发任务,任务调度系统会让所有用户的任务分时复用时间片。
CSMA/CD vs 交换式以太网
- CSMA/CD网卡需要不断监听冲突并重试。
- 交换式以太网卡只需要发包,交换机会排队调度来不及转发的数据包。
Apache vs Nginx
- Apache线程/进程若没被调度到CPU,就需要等待直到被调度切换至CPU。
- Nginx只需将事件通知到,工作进程便会轮询处理完所有请求。
共享内存 vs erlang/go channel
- 共享内存访问需要加锁,若持锁失败,要么忙等重试,要么待会儿再来。
- erlang/go channel以消息传递通信,消息发出后就不用管了,除非它希望得到回馈,完全异步。
可见,这又是一个殊途同归。同类的还有:
- PCI vs PCIe,从总线到交换。
- 宏内核 vs 微内核,从共享数据结构到消息传递。
- Spin/RW Lock vs RCU Lock,从争抢锁到操作副本原子更新。
为什么冲突仲裁的争抢模式无法承载大并发,因为过载的冲突仲裁开销会将资源淹没,若要承载大并发,必然要采用调度的方式。要理解这一要素,需要换一个视角。
我们看操作的是信息的本身还是信息的副本。
回到本文题目,“以通信方式共享内存”操作信息的副本, 而“以共享内存方式通信”则操作信息本身。
操作信息副本可以保证同时有且只有一个实体操作该副本,如果有两个实体需要操作该副本,那就再复制一个副本,这就保证了无冲突,业务流是可控无阻塞的。
RCU可做到业务无阻塞并发,无论是spinlock还是rwlock,都做不到。spinlock/rwlock锁临界区,造成临界区串行化,而RCU没临界区,它将本属于临界区的逻辑作为副本操作,择机原子更新,这便可做到无阻塞并发。
操作副本是无阻塞并发的甘泉,如果把并发看作是时间扩展性,那么将信息共享到远方则是空间扩展性,完成这件事的是网络,目前它是TCP/IP网络。TCP/IP网络采用了“以通信方式共享内存”的方式,它无疑是正确的。
我不懂erlang,但大致知道它的意思,erlang没有变量,只操作副本,它是通信网络在编程语言上的映射,对于golang,大概也是如此,使用go channel可以像网络收发一样来处理信息。
我们看socket接口,它实属用通信的方式共享内存的古老方式。
socket接口一开始是进程间通信机制,与之通信的进程可在本机,也可在远处,可在世界任意地方。“以通信方式共享内存“,是最原始的编程模式,一直到现在依然正确。
共享内存是一种本地优化,仅有编程意义,却没有扩展性,无论是无阻塞并发的时间扩展性,还是将信息传递给远方的空间扩展性。
共享内存是一种本地优化,优化的是指令操作延时,与其将信息封装成消息并传递,不如直接操作信息本身,它编程更简单,代码指令更少,执行延时更低。但高并发并不care指令延时,高并发care同时执行的有效指令数,而spin,switch不属于有效指令,故共享内存天生不与高并发配对。
此外,还是那个观点,网络编程场景,普遍毫秒级的单流通信延时,共享内存相比消息传递节省个微妙甚至纳秒级的操作延时,并无太大意义。要怪就怪光速吧。
上周周中,一个经理提到了“以通信方式共享内存,不要以共享内存方式通信”这句话,周末写篇杂感。
浙江温州皮鞋湿,下雨进水不会胖。
-
linux实现共享内存同步的四种方法
2021-05-11 12:29:01共享内存是一种最为高效的进程间通信方式,进程可以直接读写内存,而不需要任何数据的拷贝。它是IPC对象的一种。为了在多个进程间交换信息,内核专门留出了一块内存区,可以由需要访问的进程将其映射到自己的私有...https://blog.csdn.net/sunxiaopengsun/article/details/79869115
本文主要对实现共享内存同步的四种方法进行了介绍。
共享内存是一种最为高效的进程间通信方式,进程可以直接读写内存,而不需要任何数据的拷贝。它是IPC对象的一种。
为了在多个进程间交换信息,内核专门留出了一块内存区,可以由需要访问的进程将其映射到自己的私有地址空间。进程就可以直接读写这一内存区而不需要进行数据的拷贝,从而大大提高的效率。
同步(synchronization)指的是多个任务(线程)按照约定的顺序相互配合完成一件事情。由于多个进程共享一段内存,因此也需要依靠某种同步机制,如互斥锁和信号量等 。
信号灯(semaphore),也叫信号量。它是不同进程间或一个给定进程内部不同线程间同步的机制。信号灯包括posix有名信号灯、 posix基于内存的信号灯(无名信号灯)和System V信号灯(IPC对象)
方法一、利用POSIX有名信号灯实现共享内存的同步
有名信号量既可用于线程间的同步,又可用于进程间的同步。
两个进程,对同一个共享内存读写,可利用有名信号量来进行同步。一个进程写,另一个进程读,利用两个有名信号量semr, semw。semr信号量控制能否读,初始化为0。 semw信号量控制能否写,初始为1。
读共享内存的程序示例代码如下
semr = sem_open("mysem_r", O_CREAT | O_RDWR , 0666, 0);
if (semr == SEM_FAILED)
{
printf("errno=%d\n", errno);
return -1;
}
semw = sem_open("mysem_w", O_CREAT | O_RDWR, 0666, 1);
if (semw == SEM_FAILED)
{
printf("errno=%d\n", errno);
return -1;
}
if ((shmid = shmget(key, MAXSIZE, 0666 | IPC_CREAT)) == -1)
{
perror("semget");
exit(-1);
}
if ((shmadd = (char *)shmat(shmid, NULL, 0)) == (char *)(-1))
{
perror("shmat");
exit(-1);
}
while (1)
{
em_wait(semr);
printf("%s\n", shmadd);
sem_post(semw);
}
写共享内存的程序示例代码如下
。。。。。。
//同读的程序
while (1)
{
sem_wait(semw);
printf(">");
fgets(shmadd, MAXSIZE, stdin);
sem_post(semr);
}
方法二、利用POSIX无名信号灯实现共享内存的同步
POSIX无名信号量是基于内存的信号量,可以用于线程间同步也可以用于进程间同步。若实现进程间同步,需要在共享内存中来创建无名信号量。
因此,共享内存需要定义以下的结构体。
typedef struct
{
sem_t semr;
sem_t semw;
char buf[MAXSIZE];
}SHM;
读、写程序流程如下图所示。
方法三、利用System V的信号灯实现共享内存的同步
System V的信号灯是一个或者多个信号灯的一个集合。其中的每一个都是单独的计数信号灯。而Posix信号灯指的是单个计数信号灯
System V 信号灯由内核维护,主要函数semget,semop,semctl 。
一个进程写,另一个进程读,信号灯集中有两个信号灯,下标0代表能否读,初始化为0。 下标1代表能否写,初始为1。
程序流程如下:
写的流程和前边的类似。
方法四、利用信号实现共享内存的同步
信号是在软件层次上对中断机制的一种模拟,是一种异步通信方式。利用信号也可以实现共享内存的同步。
思路:
reader和writer通过信号通信必须获取对方的进程号,可利用共享内存保存双方的进程号。
reader和writer运行的顺序不确定,可约定先运行的进程创建共享内存并初始化。
利用pause, kill, signal等函数可以实现该程序(流程和前边类似)。
linux 实现共享内存同步
本文主要对实现共享内存同步的四种方法进行了介绍. 共享内存是一种最为高效的进程间通信方式,进程可以直接读写内存,而不需要任何数据的拷贝.它是IPC对象的一种. 为了在多个进程间交换信息,内核专门留出了 ...
linux下查看mysql版本的四种方法
Linux查看MySQL版本的四种方法 1 在终端下执行 mysql -V 2 在help中查找 mysql --help |grep Distrib 3 在mysql 里查看 select vers ...
关于windows线程同步的四种方法
#include "stdafx.h" #include "iostream" #include "list" #include " ...
Linux测试端口的连通性的四种方法
目录 1.telnet 2.ssh 3.crul 4.wget 方法一.telnet telnet为用户提供了在本地计算机上完成远程主机工作的能力,因此可以通过telnet来测试端口的连通性,具体用法 ...
Linux进程间通信—共享内存
五.共享内存(shared memory) 共享内存映射为一段可以被其他进程访问的内存.该共享内存由一个进程所创建,然后其他进程可以挂载到该共享内存中.共享内存是最快的IPC机制,但由于linux本身 ...
linux 下共享内存
一.共享内存相关知识 所谓共享内存,就是多个进程间共同地使用同一段物理内存空间,它是通过将同一段物理内存映射到不同进程的 虚拟空间来实现的.由于映射到不同进程的虚拟空间中,不同进程可以直接使用,不需要 ...
【Linux】多线程同步的四种方式
背景问题:在特定的应用场景下,多线程不进行同步会造成什么问题? 通过多线程模拟多窗口售票为例: #include #include ...
linux下实现web数据同步的四种方式(性能比较)
实现web数据同步的四种方式 ======================================= 1.nfs实现web数据共享2.rsync +inotify实现web数据同步3.rsyn ...
实现web数据同步的四种方式
http://www.admin10000.com/document/6067.html 实现web数据同步的四种方式 1.nfs实现web数据共享 2.rsync +inotify实现web数据同步 ...
随机推荐
SharePoint 2013技巧分享系列 - 隐藏Blog和Apps左侧导航菜单
企业内部网中,不需要员工创建Blog或者创建,安装SharePoint应用,因此需要在员工个人Web页面需要隐藏Blog或者Apps导航菜单, 其步骤设置如下: 该技巧适合SharePoint 201 ...
一次更愚蠢的NOIP模拟赛
都可以从COGS上找到 纵横字谜(krizaljka) 时间限制: 1 Sec 内存限制: 32 MB 题目描述 给出两个单词,找到第一个相同的字母,然后第一个单词横数输出,第二个竖着输出形成十字形 ...
解决pageControl页面设置无效问题
废话不多说,先上代码 1.添加pageViewControl - (void)addPageControl { UIPageControl *pageControl = [[UIPageControl ...
Git基础 - git blame
当想知道一段代码历史上有哪些人修改时,可以使用git blame查看,正如其名,当你看到那段让你抓狂的代码时,一定想找出是谁写的来一顿blame吧 : ) 使用方法 icebug@localhost: ...
sublimetext3 安装php语法检测
打开控制台,install package 搜 sublimelinter 先安装sublimelinter本体 安装完以后再搜索一下,安装sublimelinter-php 接下来,打开prefer ...
DevExpress BarManager 部分用法
1.创建一个BarManager会默认产生三个菜单.BarManager右键ShowDesignTime enhancements会显示[add]按钮,可对菜单进行编辑. 2.其中比较有用的属性: 选 ...
Fedora20 编译安装qemu-system
安装简介: 1.1. 本次编译安装所有的操作都在Fedora 20 x86-64上,内核版本为: 3.14.4-200.fc20.x86_64.如果在其他系统编译安装,请看其他文章. 2.安装准备: ...
PostgreSQL的 initdb 源代码分析之十一
继续分析: /* Top level PG_VERSION is checked by bootstrapper, so make it first */ write_version_file(NUL ...
centos SSH配置详解
基本概念 linux自带的ssh为OpenSSH ssh协议提供两种用户认证方式 1. 基于口令的安全认证:使用用户名.密码的方式对登录用户进行认证 2. 基于密钥的安全认证:使用公钥和私钥对的方 ...
最近采用Instruments
最近采用Instruments 来分析整个应用程序的性能.发现很多有意思的点,以及性能优化和一些分析性能消耗的技巧,小结如下. Instruments使用技巧 关于Instruments官方有一个很有 ...
-
linux共享内存的两种方式
2017-05-04 11:45:28linux共享内存有两种方式: 第一种:mmap方式,适用场景:父子进程之间 第二种:shmget方式,适用场景:同一台电脑上不同进程之间 两种方式的文档网上都有很多,随便一抓一把。 通病:共享内存没有自带的同步机制,... -
进程间的通信方式(一):共享内存
2018-06-07 15:22:37共享内存指 (shared memory)在多处理器的计算机系统中,可以被不同中央处理器(CPU)访问的大容量内存。由于多个CPU需要快速访问存储器,这样就要对存储器进行缓存(Cache)。任何一个缓存的数据被更新后,由于其他... -
Linux共享内存
2022-02-04 22:56:58共享存储允许两个或多个进程共享一个给定的存储区,是进程间通信最快的一种方式。 不要同时对共享存储空间进行写操作,通常,信号量用于同步共享存储访问。 最简单的共享内存的使用流程 ①ftok函数生成键值 ②shmget... -
Linux进程间通信的两种方式:使用共享内存和信号量
2017-10-08 22:01:52共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式。不同进程之间共享的内存通常安排为同一段物理内存。进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的... -
【操作系统】 为什么说共享内存是最快的一种IPC方式呢?
2020-04-01 02:15:52在linux进程间通信的方式中,共享内存是一种最快的IPC方式。因此,共享内存用于实现进程间大量的数据传输,共享内存的话,会在内存中单独开辟一段内存空间,这段内存空间有自己特有的数据结构,包括访问权限、大小和... -
【Linux】Linux的共享内存
2018-08-10 19:17:45由于进程可以直接对共享内存进行读写操作,因此这种通信方式效率特别高,但其弱点是,它没有互斥机制,需要信号量之类的手段来配合。 共享内存原理与shm系统 共享内存,顾名思义,就是两个或多个进程都可以... -
共享内存实现原理
2018-09-28 18:02:39共享内存的使用实现原理(必考必问,然后共享内存段被映射进进程空间之后,存在于进程空间的什么位置?共享内存段最大限制是多少?) nmap函数要求内核创建一个新额虚拟存储器区域,最好是从地质start开始的一个... -
python进程通信方式总结(三):共享内存
2021-02-16 14:01:57引言 python使用共享内存进行通信 -
宋宝华:世上最好的共享内存(Linux共享内存最透彻的一篇)
2019-12-09 07:52:58共享单车、共享充电宝、共享雨伞,世间的共享有千万种,而我独爱共享内存。早期的共享内存,着重于强调把同一片内存,map到多个进程的虚拟地址空间(在相应进程找到一个VMA区域),以便于CPU... -
什么是共享内存?在内存中的具体位置?共享内存相关API,mmap 的具体使用原理、以及C++应用案例?
2020-08-01 00:23:30共享内存允许两个或多个进程共享一给定的存储区,因为数据不需要来回复制,所以是最快的一种进程间通信机制。共享内存可以通过mmap()映射普通文件 (特殊情况下还可以采用匿名映射)机制实现,也可以通过系统V共享... -
python的共享内存处理
2021-10-18 17:18:51共享内存是两个正在运行的进程之间共享和传递数据的一种非常有效的方式。进程可以将同一段物理内存连接到他们自己的地址空间中,所有的进程都可以访问共享内存中的地址。如果某个进程向共享内存写入数据,所做的改动... -
进程间通信方式——共享内存
2017-05-22 23:30:38进程间通信方式共享内存和与共享内存函数详解,以及模拟共享内存实现进程间通信,以及共享内存的优缺点。 -
Linux下进程间通信 之 共享内存
2021-12-14 17:19:05共享内存是在两个或多个正在运行的进程之间共享内存区域的一种进程间的通信方式(就是 允许两个或多个不相关的进程访问同一个逻辑内存)。是 IPC中最快捷的通信方式,因为共享内存 方式的通信没有中间过程,而管道... -
Linux 多进程通信开发(六): 共享内存
2019-04-10 19:11:37前面的文章一系列文章有介绍了 linux 下常见的 IPC 机制,如管道、消息队列、信号量,今天这篇文章介绍一下最核心的机制,那就是共享内存,因为它是最高效的 IPC 方式。 什么是共享内存? 共享内存其实很容易理解,... -
Linux 下三种共享内存方式
2015-03-29 16:33:36共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式。两个不同进程A、B共享内存的意思是,同一块物理内存被映射到进程A、B各自的进程地址空间。进程A可以即时看到进程B对共享内存中数据的更新,反之亦然。... -
optee的共享内存的介绍
2020-08-20 20:10:24optee支持两种share memory: 连续的buffer,非连续的buffer optee是按照buffer来管理共享内存的,而不是按照pool来管理的. 每一个buf需要配置如下属性: buffer的起始地址和size 该buffer的cache属性 如果是被map到... -
c++共享内存通信如何实现
2020-01-13 12:11:23现在很多对性能要求高的项目都会支持共享内存的进程间通信(IPC)方式,本文会以百度Apollo自动驾驶项目为例,展示两种c++中实现共享内存通信的方式(对应linux中两种不同的机制)。 -
进程间通信——共享内存(Shared Memory)
2018-04-16 16:19:17共享内存,顾名思义就是允许两个不相关的进程访问同一个逻辑内存,共享内存是两个正在运行的进程之间共享和传递数据的一种非常有效的方式。不同进程之间共享的内存通常为同一段物理内存。进程可以将同一段物理内存... -
Linux下共享内存编程(共享存储空间)
2018-07-29 23:44:08共享存储允许两个或多个进程共享一个给定的存储区,是进程间通信最快的一种方式。 不要同时对共享存储空间进行写操作,通常,信号量用于同步共享存储访问。 最简单的共享内存的使用流程 ①ftok函数生成键值 ②... -
共享内存
2018-09-19 15:38:10共享内存是在两个正在运行的进程之间传递数据的一种非常有效的方式。共享内存的具体实现是不同进程共享的内存安排为同一段物理地址。 如上图所示,进程A和进程B共享同一块物理内存,共享内存中的数据进程A和... -
【进程间通信2】使用共享内存实现进程间的通信(附C++实现代码)
2022-01-18 18:23:09共享内存的创建,以及亲缘进程和非亲缘进程之间的如何使用共享内存。 -
Qt共享内存的使用
2018-05-18 09:52:10Qt主要是通过QSharedMemory类来访问以及操作共享内存。 以下是几个主要的步骤 1.对于QsharedMemory类的对象进行创建 利用QSharedMemory类创建实例对象时,...为共享内存指定关键字有两种方法: a.直接在通过构造... -
共享内存(进程通信)
2017-05-20 17:26:35前面介绍了进程通信的几种方式,信号量,管道,消息队列,今天主要总结下共享内存的知识点。什么是共享内存我们一张图来解释什么叫共享内存。我们知道,每个进程都有一个叫PCB(Linux下一般为task _ struct)的数据... -
世上最好的共享内存(Linux共享内存最透彻的一篇)
2020-07-17 11:25:36共享单车、共享充电宝、共享雨伞,世间的共享有千万种,而我独爱共享内存。 早期的共享内存,着重于强调把同一片内存,map到多个进程的虚拟地址空间(在相应进程找到一个VMA区域),以便于CPU可以在各个进程访问到...