-
2020-05-29 11:04:23
共享内存多核系统与分布式内存系统之间的区别
我们经常说到的多核处理器,是指一个处理器(CPU)上有多个处理核心(CORE),共享内存多核系统我们可以将CPU想象为一个密封的包,在这个包内有多个互相连接的CORES,每个CORE共享一个主存,所有的处理核心都可以访问主存。
分布式内存系统是由多个处理器(CPU)组成,每个处理器可以位于不同的计算机上,并且都有自己私有的内存。MPI(message passing interface)是运行在分布式计算机系统上的并行应用程序所使用的最流行的通信协议。在分布式计算机系统中,当某个处理器上的作业需要远程数据时,这个作业需要通过通信信道与远程处理器进行通信(此时,就用到了MPI)。因此MPI主要关注的是帮助开发在集群上运行的应用程序。
在共享内存的多核系统中,MPI会带来没有必要的额外开销,因为所有的内核都可以访问主存,所以没有必要发送消息。
更多相关内容 -
nginx共享内存
2022-03-16 20:42:141 共享内存数据结构 typedef struct { u_char *addr; //共享内存地址 size_t size; //内存大小 ngx_str_t name; //共享内存名称 ngx_log_t *log; //log ngx_uint_t exists; /* unsigned exists:1; ...1 共享内存申请
共享内存申请比较简单,这里采用的是Linux系统共享内存分配的函数实现的。
#include <sys/ipc.h> #include <sys/shm.h> ngx_int_t ngx_shm_alloc(ngx_shm_t *shm) { int id; id = shmget(IPC_PRIVATE, shm->size, (SHM_R|SHM_W|IPC_CREAT)); if (id == -1) { ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, "shmget(%uz) failed", shm->size); return NGX_ERROR; } ngx_log_debug1(NGX_LOG_DEBUG_CORE, shm->log, 0, "shmget id: %d", id); shm->addr = shmat(id, NULL, 0); if (shm->addr == (void *) -1) { ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, "shmat() failed"); } if (shmctl(id, IPC_RMID, NULL) == -1) { ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, "shmctl(IPC_RMID) failed"); } return (shm->addr == (void *) -1) ? NGX_ERROR : NGX_OK; } void ngx_shm_free(ngx_shm_t *shm) { if (shmdt(shm->addr) == -1) { ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, "shmdt(%p) failed", shm->addr); } }
2 共享内存实现原理
2.1 共享内存组织
共享内存的管理工作是在:ngx_cycle内完成,主要是利用一个list进行组织。
首先是ngx_list组织形式,采用的是将多个ngx_list_part单元串行组成的链表;同时每个ngx_list_part是由多个ngx_shm_zone_t组成构成。这样做的一个好处就是一次预先分配一个元素组,只有当第一个元素组用完才会申请新的元素组。可以达到减少频繁分配的问题。
这里需要展开对应ngx_shm_zone单元的介绍:
首先是用户定义自己的数据结构并存入data中;第二部分是初始化函数,用户获取到ngx_shm_zone_t 共享内存单元的时候需要注册自己数据结构的初始化函数,其中zone返回是当前的共享内存的数据,而data返回的是上一次初始化的数据即历史数据;tag存放的是创建共享内存的模块;ngx_shm_t共享内存基本信息包括地址,大小,名称,log输出位置等。typedef struct { u_char *addr;//共享内存地址 size_t size;//大小 ngx_str_t name;//名称 ngx_log_t *log; ngx_uint_t exists; /* unsigned exists:1; */ } ngx_shm_t; typedef ngx_int_t (*ngx_shm_zone_init_pt) (ngx_shm_zone_t *zone, void *data); struct ngx_shm_zone_s { void *data;//用户数据 ngx_shm_t shm; //共享内存结构体 ngx_shm_zone_init_pt init;//用户数据的初始化函数 void *tag;//创建的模块 ngx_uint_t noreuse; /* unsigned noreuse:1; */ };
初始化函数具体调用位置是在创建完共享内存后即进行初始化ngx_init_cycle函数中进行:
2.2 slab共享内存管理机制
slab内存分配方式是共享内存的管理机制,主要是利用最优选择的思路,当我们申请内存块时只会返回恰好符合请求大小的内存块。基本原理是把内存按照4k一页分成若干页,将每页放置不同大小的内存块,然后利用bitmap在页首进行标识内存块是否被使用。只需要变量bitmap查找空闲的内存块从而提高查找效率。
将存放不同大小的内存块的页面利用链表顺序串联,这样利用slots数组存放链表的首页。这样可以直接根据要分配内存大小进行寻址。
这里还有一个小操作提高查找空闲内存,当一个页面没有空闲的内存块时需要从队列中脱离变成一个单独的节点。2.3 slab与ngx_shm_zone_t 关系
整体的初始化动作是在ngx_init_zone_pool函数进行:利用shm中addr存放slab_pool对象,并完成slab的初始化动作。
ngx_slab_pool_t *sp; sp = (ngx_slab_pool_t *) zn->shm.addr; sp->addr = zn->shm.addr; ngx_slab_init(sp);
3 共享内存应用
共享内存的使用场景,这里分析ssl模块的共享内存使用方法,可以推广到其他模块使用。
首先是是进行共享内存的ngx_shm_zone_t分配,这是一个比较简单的操作,从共享内存返回一块空闲的shm_zone.ngx_shm_zone_t *shm_zone;//共享内存单元 ngx_conf_t *cf;//ngx配置 ngx_str_t name;//共享内存名称 ngx_int_t n;//分配共享内存的大小 ngx_module_t ngx_stream_ssl_module;//使用共享内存的模块,防止模块间重名 scf->shm_zone = ngx_shared_memory_add(cf, &name, n,&ngx_stream_ssl_module);//从 if (scf->shm_zone == NULL) { return NGX_CONF_ERROR; } //初始化函数设置 scf->shm_zone->init = ngx_ssl_session_cache_init;
初始化函数:data返回的是上一次分配的数据,如果存在直接返回。否则先取出slab_pool进程分配操作调用ngx_slab_alloc分配一个内存块大小,可以是数据结构。这里分配的是一个红黑树结构,分配完成后就可以直接初始化红黑树。
ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data) { size_t len; ngx_slab_pool_t *shpool; ngx_ssl_session_cache_t *cache; if (data) { shm_zone->data = data; return NGX_OK; } //获取slab_pool shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; if (shm_zone->shm.exists) { shm_zone->data = shpool->data; return NGX_OK; } //为数据分配slab内存块 cache = ngx_slab_alloc(shpool, sizeof(ngx_ssl_session_cache_t)); if (cache == NULL) { return NGX_ERROR; } //赋值到slab_pool管理 shpool->data = cache; shm_zone->data = cache; //红黑树数据初始化 ngx_rbtree_init(&cache->session_rbtree, &cache->sentinel, ngx_ssl_session_rbtree_insert_value); //队列初始化 ngx_queue_init(&cache->expire_queue); //设置log len = sizeof(" in SSL session shared cache \"\"") + shm_zone->shm.name.len; //为log分配共享内存 shpool->log_ctx = ngx_slab_alloc(shpool, len); if (shpool->log_ctx == NULL) { return NGX_ERROR; } //写log ngx_sprintf(shpool->log_ctx, " in SSL session shared cache \"%V\"%Z", &shm_zone->shm.name); shpool->log_nomem = 0; return NGX_OK; }
-
以通信方式共享内存,不要以共享内存方式通信
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共享内存设置
2015-08-09 12:45:30最近频繁遇到共享内存的问题,这里总结一下一些设置: cat /proc/sys/kernel/shmmax cat /proc/sys/kernel/shmmni cat /proc/sys/kernel/shmall 临时修改这三个参数的值,通过echo或sysctl命令修改proc文件中的...最近频繁遇到共享内存的问题,这里总结一下一些设置:
cat /proc/sys/kernel/shmmax
cat /proc/sys/kernel/shmmni
cat /proc/sys/kernel/shmall
临时修改这三个参数的值,通过echo或sysctl命令修改proc文件中的值,重启失效
echo 1073741824 > /proc/sys/kernel/shmmax
sysctl -w kernel.shmmax=1073741824 # 1GB
echo "kernel.shmmax=1073741824" 》 /etc/sysctl.conf
我们可以修改shmmax内核参数,使SGA存在于一个共享内存段中。通过修改/proc/sys/kernel/shmmax参数可以达到此目的。
[root@neirong root]# echo 1073741824 > /proc/sys/kernel/shmmax
[root@neirong root]# more /proc/sys/kernel/shmmax
1073741824这里设为1G。
对于shmmax文件的修改,系统重新启动后会复位。可以通过修改 /etc/sysctl.conf 使更改永久化。
在该文件内添加以下一行 kernel.shmmax = 1073741824 这个更改在系统重新启动后生效.
1、设置 SHMMAX
SHMMAX
参数定义共享内存段的最大尺寸(以字节为单位)。在设置 SHMMAX 时,切记 SGA 的大小应该适合于一个共享内存段。 SHMMAX 设置不足可能会导致以下问题:
ORA-27123:unable to attach to shared memory segment
您可以通过执行以下命令来确定 SHMMAX 的值:
# cat /proc/sys/kernel/shmmax
33554432
SHMMAX 的默认值是 32MB 。我一般使用下列方法之一种将 SHMMAX 参数设为 2GB :
通过直接更改 /proc 文件系统,你不需重新启动机器就可以改变 SHMMAX 的默认设置。我使用的方法是将以下命令放入 /etc/rc.local 启动文件中:
# >echo "2147483648" > /proc/sys/kernel/shmmax
您还可以使用 sysctl 命令来更改 SHMMAX 的值:
# sysctl -w kernel.shmmax=2147483648
最后,通过将该内核参数插入到 /etc/sysctl.conf 启动文件中,您可以使这种更改永久有效:
# echo "kernel.shmmax=2147483648" >> /etc/sysctl.conf
2、设置 SHMMNI
我们现在来看 SHMMNI 参数。这个内核参数用于设置系统范围内共享内存段的最大数量。该参数的默认值是 4096 。这一数值已经足够,通常不需要更改。
您可以通过执行以下命令来确定 SHMMNI 的值:
# cat /proc/sys/kernel/shmmni
4096
3、设置 SHMALL
最后,我们来看 SHMALL 共享内存内核参数。该参数控制着系统一次可以使用的共享内存总量(以页为单位)。简言之,该参数的值始终应该至少为:
ceil(SHMMAX/PAGE_SIZE)
SHMALL 的默认大小为 2097152 ,可以使用以下命令进行查询:
# cat /proc/sys/kernel/shmall
2097152
SHMALL 的默认设置对于我们的 Oracle9 i RAC 安装来说应该足够使用。
注意: 在 i386 平台上 Red Hat Linux 的 页面大小 为 4096 字节。但是,您可以使用 bigpages ,它支持配置更大的内存页面尺寸
这是实际linux系统显示的实际数据:
beijibing@bjb-desktop:/proc/sys/kernel$ cat shmmax
33554432
beijibing@bjb-desktop:/proc/sys/kernel$ cat shmmni
4096
beijibing@bjb-desktop:/proc/sys/kernel$ cat msgmax
8192
beijibing@bjb-desktop:/proc/sys/kernel$ cat msgmni
622
beijibing@bjb-desktop:/proc/sys/kernel$ cat msgmnb
16384
System V
IPC 参数 名字 描述 合理取值 SHMMAX 最大共享内存段尺寸(字节) 最少若干兆(见文本) SHMMIN 最小共享内存段尺寸(字节) 1 SHMALL 可用共享内存的总数量(字节或者页面) 如果是字节,就和 SHMMAX 一样;如果是页面,ceil(SHMMAX/PAGE_SIZE) SHMSEG 每进程最大共享内存段数量 只需要 1 个段,不过缺省比这高得多。 SHMMNI 系统范围最大共享内存段数量 类似 SHMSEG 加上用于其他应用的空间 SEMMNI 信号灯标识符的最小数量(也就是说,套) 至少ceil(max_connections / 16) SEMMNS 系统范围的最大信号灯数量 ceil(max_connections / 16) * 17 加上用于其他应用的空间 SEMMSL 每套信号灯最小信号灯数量 至少 17 SEMMAP 信号灯映射里的记录数量 参阅文本 SEMVMX 信号灯的最大值 至少 1000 (缺省通常是32767,除非被迫,否则不要修改) 最重要的共享内存参数是
SHMMAX , 以字节记的共享内存段可拥有的最大尺寸。如果你收到来自 shmget
的类似Invalid argument 这样的错误信息,那么很有可能是你超过限制了。 有些系统对系统里面共享内存的总数(SHMALL
)还有限制。 请注意这个数值必须足够大。(注意:SHMALL 在很多系统上是用页面数,而不是字节数来计算的。) 系统里的最大信号灯数目是由SEMMNS
设置的,因此这个值应该至少和 max_connections 设置一样大,并且每十六个联接还要另外加一个。 参数SEMMNI 决定系统里一次可以存在的信号灯集的数目。 因此这个参数至少应该为 ceil(max_connections % 16) 。降低允许的联接数目是一个临时的绕开失败的方法,这个启动失败通常被来自函数 semget
的错误响应 No space left on device 搞得很让人迷惑。 有时候还可能有必要增大SEMMAP
,使之至少按照 SEMMNS 配置。这个参数定义信号灯资源映射的尺寸,可用的每个连续的信号灯块在这个映射中存放一条记录。每当一套信号灯被释放,那么它要么会加入到该映射中一条相连的已释放的块的入口中,要么注册成一条新的入口。如果映射填满了碎片,那么被释放的信号灯就丢失了(除非重起)。因此时间长信号灯空间的碎片了会导致可用的信号灯比应该有的信号灯少。 SEMMSL
参数,决定一套信号灯里可以有多少信号灯, 更改方法
-
Linux
-
缺省设置只适合小安装(缺省最大共享内存是 32 MB)。不过,其它的缺省值都相当大,通常不需要改变。最大的共享内存段设置可以用
sysctl 接口设置。 比如,要允许 128 MB,并且最大的总共享内存数为 2097152 页(缺省): $ sysctl -w kernel.shmmax=134217728 $ sysctl -w kernel.shmall=2097152
你可以把这些设置放到
/etc/sysctl.conf 里,在重启后保持有效。 老版本里可能没有
sysctl 程序,但是同样的改变可以通过操作 /proc 文件系统来做: $ echo 134217728 >/proc/sys/kernel/shmmax $ echo 2097152 >/proc/sys/kernel/shmall
另外可行的方法:
修改方法如下: 修改/etc/rc.d/rc.local文件。在文件的前面注释的后面加入以下行:
#修改内核共享内存大小;
echo134217728>/proc/sys/kernel/shmmax;
#说明:这里的值为内存的一半;
#如果系统内存是256M,则值为134217728;
#如果系统内存是512M,则值为268435456;
修改完成以后,重起机器就搞定。
其它系统的修改方法
-
MacOS X
-
在 OS X 10.2 以及更造版本里, 编辑文件
/System/Library/StartupItems/SystemTuning/SystemTuning 并且用下列命令修改这些数值: sysctl -w kern.sysv.shmmax sysctl -w kern.sysv.shmmin sysctl -w kern.sysv.shmmni sysctl -w kern.sysv.shmseg sysctl -w kern.sysv.shmall
在 OS X 10.3 及以后的版本里,这些命令移动到
/etc/rc 里面去了,必须在那里编辑。你需要重新启动才能让设置生效。请注意/etc/rc 通常会被 OS X 更新覆盖 (比如 10.3.6 到 10.3.7),所以每次更新后你可能都需要重新编辑。 在这个平台上,SHMALL
是用 4KB 页来度量的。 还要注意有些版本的 OS X 将拒绝把 SHMMAX 的数值数值为非 4096 的倍数。
SCO OpenServer
-
缺省配置时,只允许每段 512KB 共享内存。 要增大设置,首先进入
/etc/conf/cf.d 目 录。要显示当前的以字节记的 SHMMAX ,运行 ./configure -y SHMMAX
设置
SHMMAX 的新值: ./configure SHMMAX=value
这里
value 是你想设置的以字节记的新值。设置完了以后SHMMAX 重新制作内核 ./link_unix
然后重起。
AIX
-
至少对于版本 5.1 而言,我们有必要为类似
SHMMAX 这样的参数做特殊的配置,因为这个参数可以配置为所有内容都当作共享内存使用。这就是类似 DB/2 这样的数据库常用的配置。 不过,我们可能有必要在
/etc/security/limits 里面修改全局 ulimit ulimit 信息,因为文件大小的缺省硬限制(fsize )以及文件数(nofiles )可能太低了。
Solaris
-
至少到版本 2.6 为止,共享内存段的缺省最大设置对
PostgreSQL 来说是太低了。相关的设置可以在/etc/system 里面修改,例如: set shmsys:shminfo_shmmax=0x2000000 set shmsys:shminfo_shmmin=1 set shmsys:shminfo_shmmni=256 set shmsys:shminfo_shmseg=256 set semsys:seminfo_semmap=256 set semsys:seminfo_semmni=512 set semsys:seminfo_semmns=512 set semsys:seminfo_semmsl=32
你要重起系统令修改生效。
又见
http://sunsite.uakom.sk/sunworldonline/swol-09-1997/swol-09-insidesolaris.html 获取关于 Solaris 里面的共享内存的信息。
UnixWare
-
在
UnixWare 7 上,缺省配置里的最大共享内存段是 512 kB。 要显示SHMMAX 的当前值,运行 /etc/conf/bin/idtune -g SHMMAX
就会显示以字节记的当前的缺省的最小和最大值。 要给SHMMAX
设 置一个新值,运行: /etc/conf/bin/idtune SHMMAX value
这里
value 是你想设置的以字节记的新值。设置完SHMMAX 后,重建内核 /etc/conf/bin/idbuild -B
然后重起。
BSD/OS
-
共享内存.
缺省时是只支持 4 MB 的共享内存。请记住共享内存是不能分页的;它是锁在 RAM 里面的。要增加你的系统支持的共享缓冲区数目,向你的内核配置文件里增加下面的行: options "SHMALL=8192" options "SHMMAX=\(SHMALL*PAGE_SIZE\)"
SHMALL
以 4KB 页为单位计算,所以 1024 页面代表 4 M 共享内存。 所以上面的东西把共享内存区域增加到 32 MB。 对于运行 4.3 或者更新版本的人,你可能需要增大 KERNEL_VIRTUAL_MB ,超过缺省的 248 。 做完上面的修改之后,然后编译内核并重起。 对于运行 4.0 或者更早的版本的, 请用
bpatch 找出当前内核的 sysptsize 值。它是启动的时候动态计算的。 $ bpatch -r sysptsize 0x9 = 9
然后,把
SYSPTSIZE 修改为在内核配置文件里的一个硬代码值。用 bpatch 算出来的值,并且为你需要的每个额外的 4 MB 共享内存再加 1。 options "SYSPTSIZE=16"
sysptsize
不能用 sysctl 修改。 信号灯.
你可能还需要增加信号灯的数量;系统缺省的总数 60 只能允许大概 50 个 PostgreSQL 连接。在内核配置文件里设置你需要的值,比如: options "SEMMNI=40" options "SEMMNS=240"
FreeBSD
-
缺省设置只适合于很小的安装(比如,缺省
SHMMAX 是 32 MB)。我们可以用 sysctl 或者 loader 接口来修改。下面的参数可以用 sysctl 设置: $ sysctl -w kern.ipc.shmall=32768 $ sysctl -w kern.ipc.shmmax=134217728 $ sysctl -w kern.ipc.semmap=256
要想让这些设置重启后有效,修改
/etc/sysctl.conf 。 如果用
sysctl ,那么剩下的信号灯设置是只读的,但是信号灯可以在启动的时候,在 loader 提示符下设置: (loader) set kern.ipc.semmni=256 (loader) set kern.ipc.semmns=512 (loader) set kern.ipc.semmnu=256
类似的,这些东西可以在
/boot/loader.conf 中保存,以便重启之后依然有效。 你可能还想配置内核,让把共享内存装载到 RAM 里,避免他们被交换到交换分区中。这些可以通过使用
sysctl 设置kern.ipc.shm_use_phys 来实现。 在 4.0 之前的
FreeBSD 版本类似 NetBSD 和 OpenBSD (见下文)。
NetBSD
-
编译内核时需要把选项
SYSVSHM 和 SYSVSEM 打开。(缺省是打开的。)共享内存的最大尺寸是由选项SHMMAXPGS (以页计)。下面显示了一个如何设置这些参数的例子(OpenBSD 使用的是 option ): options SYSVSHM options SHMMAXPGS=4096 options SHMSEG=256 options SYSVSEM options SEMMNI=256 options SEMMNS=512 options SEMMNU=256 options SEMMAP=256
你可能原意使用
sysctl 设置将共享内存锁在 RAM 中以避免它们被交换出去,我们可以用 sysctl 设置kern.ipc.shm_use_phys 来实现这个目的。
HP-UX
-
缺省设置看来对普通安装是足够的了。 在
HP-UX 10,SEMMNS 的出厂缺省是 128,可能对大的数据库节点来说太小了。 IPC
可以在 System Administration Manager(系统管理器) (SAM )下面的 Kernel Configuration ->Configurable Parameters 配置。你配置完了以后敲 Create A New Kernel 选项。
OpenBSD -
-
-
Qt 读写共享内存
2020-10-01 14:05:43Qt 读写共享内存 一、简述 记--使用Qt进行简单的读写共享内存。 二、工程结构 三、测试代码 #include <QDebug> #include <QSharedMemory> //测试使用的数据结构 typedef struct{ int age; ... -
【Linux】Linux的共享内存
2018-08-10 19:17:45实现进程间通信最简单也是最直接的...共享内存原理与shm系统 共享内存,顾名思义,就是两个或多个进程都可以访问的同一块内存空间,一个进程对这块空间内容的修改可为其他参与通信的进程所看到的。 显然,为了达... -
什么是共享内存?在内存中的具体位置?共享内存相关API,mmap 的具体使用原理、以及C++应用案例?
2020-08-01 00:23:30共享内存可以通过mmap()映射普通文件 (特殊情况下还可以采用匿名映射)机制实现,也可以通过系统V共享内存机制实现。 共享内存是内核为进程创建的一个特殊内存段,它将出现在进程自己的地址空间中,其它进程可以将... -
共享内存实现原理
2018-09-28 18:02:39共享内存的使用实现原理(必考必问,然后共享内存段被映射进进程空间之后,存在于进程空间的什么位置?... SHMMNI为128,表示系统中最多可以有128个共享内存对象。 共享内存可以说是最有用的进程间通... -
宋宝华:世上最好的共享内存(Linux共享内存最透彻的一篇)上集
2019-11-08 08:00:00共享单车、共享充电宝、共享雨伞,世间的共享有千万种,而我独爱共享内存。早期的共享内存,着重于强调把同一片内存,map到多个进程的虚拟地址空间(在相应进程找到一个VMA区域),以便于CPU可以在各个进程访问到这... -
c++共享内存通信如何实现
2020-01-13 12:11:23现在很多对性能要求高的项目都会支持共享内存的进程间通信(IPC)方式,本文会以百度Apollo自动驾驶项目为例,展示两种c++中实现共享内存通信的方式(对应linux中两种不同的机制)。 -
【面试题】Linux如何实现共享内存
2019-06-25 10:09:17为什么实现共享内存? 采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝。对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而共享... -
【操作系统】Linux 进程间通信(IPC)—共享内存(System V与POSIX API实现,基于生产者消费者问题)
2022-03-23 14:31:15Linux 进程间通信(IPC)—共享内存 -
如何调整用于显卡的共享内存
2021-08-11 09:06:32主机的显卡能否通过共享内存的方式增大显存容量?需要如何操作? 显卡的显存大小如下图所示:一般情况下,仅有早期机型如 2006 年前甚至更早的机型,共享显存容量的调整功能。并且该功能只能通过 BIOS Setup 程序... -
C/C++ linux 实现共享内存(share memory)的读写操作【代码实例】
2021-07-30 15:20:32什么是共享内存? 简单来说,共享内存就是允许两个或多个进程共享一定的存储区。 -
进程间通信——共享内存(Shared Memory)
2018-04-16 16:19:17共享内存,顾名思义就是允许两个不相关的进程访问同一个逻辑内存,共享内存是两个正在运行的进程之间共享和传递数据的一种非常有效的方式。不同进程之间共享的内存通常为同一段物理内存。进程可以将同一段物理内存... -
Linux下共享内存编程(共享存储空间)
2018-07-29 23:44:08共享存储允许两个或多个进程共享一个给定的存储区,是进程间通信最快的一种方式。 不要同时对共享存储空间进行...④shmdt函数进行分离(对共享存储段操作结束时的步骤,并不是从系统中删除共享内存和结构) ⑤shm... -
Linux下进程间通信 之 共享内存
2021-12-14 17:19:05一、共享内存的概念 共享内存是在两个或多个正在运行的进程之间共享内存区域的一种进程间的通信方式(就是 允许两个或多个不相关的进程访问同一个逻辑内存)。是 IPC中最快捷的通信方式,因为共享内存 方式的通信... -
宋宝华:世上最好的共享内存(Linux共享内存最透彻的一篇)
2019-12-09 07:52:58共享单车、共享充电宝、共享雨伞,世间的共享有千万种,而我独爱共享内存。早期的共享内存,着重于强调把同一片内存,map到多个进程的虚拟地址空间(在相应进程找到一个VMA区域),以便于CPU... -
共享内存原理及实现通信过程
2022-02-14 09:25:04一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据。 进程通信的本质就是让两个进程看到同一个空间,所以共享内存... -
ROS系统学习8---节点间的内存共享(初级篇)
2018-11-28 16:13:49本篇我们回到ROS的内部,看看如何实现ROS节点间的内存共享,以实现更加快速的内部通信。 首先,我们需要清楚为什么要用内存共享? 答案是ROS提供的服务或者话题都是通过网络来实现的。这样做虽然更具普遍性,照顾... -
Linux 多进程通信开发(六): 共享内存
2019-04-10 19:11:37这会是一系列文章,讲解的内容也很简单,文章的目的是让自己的知识固话和文档化,以备自己不时的复习,同时也希望能够给予初学者一些帮助...共享内存其实很容易理解,不同的进程共享一块内存。 我们都知道,进程间通... -
【操作系统】 为什么说共享内存是最快的一种IPC方式呢?
2020-04-01 02:15:52因此,共享内存用于实现进程间大量的数据传输,共享内存的话,会在内存中单独开辟一段内存空间,这段内存空间有自己特有的数据结构,包括访问权限、大小和最近访问的时间等。 为什么说共享内存是最快的一种IPC方式呢... -
数据共享,内存映射文件和虚拟内存,共享内存
2017-09-17 16:28:28内存映射文件的物理存储器来自磁盘已有的文件,而不是来自系统的页交换文件。一旦把文件映射到地址空间,就可以对它进行访问,就好像整个文件都已经被载入内存一样。不必再对文件执行I/O操作。 使用内存映射文件... -
win10任务管理器中的专用GPU内存 vs 共享GPU内存
2020-06-08 15:58:17Win10任务管理器–>性能选项卡–>GPU选项下,会有专用GPU内存,共享GPU内存和GPU内存信息的使用情况。 ...就是GPU(s)和其他应用可以共享的系统内存,其中,GPU的使用优先级最高。 受PCIe限. -
Linux共享内存和Qt共享内存QSharedMemory的使用,今天你会了吗
2020-07-01 13:58:54Linux共享内存和Qt共享内存SharedMemory简介Linux共享内存使用Qt共享内存SharedMemory使用 简介 Linux系统下进程通信的方式有很多: 管道(pipe) 命名管道(FIFO) 内存映射(mapped memeory) 消息队列(message queue) ... -
玩转笔记本显卡共享显存设置
2021-05-11 22:57:02随着游戏复杂性的提升,新一代3D...值得庆幸的是,目前笔记本的集成显卡及移动独立显卡都支持动态显存调节技术,可以将更多系统内存共享为显存来提升性能。下面,就让我们一起来学习笔记本显卡显存的调节。Intel移... -
操作系统实验三之进程间共享内存
2017-04-09 03:18:57操作系统实验三之进程间共享内存。使用fork()编写一个c语言程序。它在子进程中生成Fibonacci数列,数列号码在命令行中提供。例如,如果提供的是5,Fibonacci数列中的前5个数将由子进程产生。在子进程生成数列之后,... -
共享内存的实现详解
2018-04-26 10:43:48一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据。共享内存示意图:共享内存数据结构:struct shmid_ds { struct ... -
linux 共享内存删除_如何列出和删除Linux中的共享内存?
2020-07-28 06:14:03linux 删除 共享内存 how to list and delete shared memory in linux? 如何在Linux中列出和删除共享内存? ... $ ipcs -m 列出您的Linux 系统中的所有共享内存 > $ ipcs -m Delete speci... -
Linux: 修改共享内存大小
2018-06-15 15:17:48这是实际linux系统显示的实际数据:beijibing@bjb-desktop:/proc/sys/kernel$ cat shmmax 33554432beijibing@bjb-desktop:/proc/sys/kernel$ cat shmmni4096beijibing@bjb-desktop:/proc/sys/kernel$ cat msgmax...