linux共享内存命令 linux 共享内存大小

linux查看共享内存命令共享内存查看
使用ipcs命令,不加如何参数时,会把共享内存、信号量、消息队列的信息都打印出来,如果只想显示共享内存信息,使用如下命令:
[root@localhost ~]# ipcs -m
------ Shared Memory Segments --------
keyshmidownerpermsbytesnattchstatus
0x00000000 1867776root6003932162dest
0x00000000 1900545root6003932162dest
0x00030021 1703938zc6661311041
0x0003802e 1736707zc6661311041
0x00030004 1769476zc6661311041
0x00038002 1802245zc6661311041
0x00000000 1933318root6003932162dest
0x00000000 1966087root6003932162dest
0x00000000 1998856root6003932162dest
0x00000000 2031625root6003932162dest
0x00000000 2064394root6003932162dest
0x0014350c 2261003cs666335544322
0x00000000 2129932root6003932162dest
0x00000000 2162701root6003932162dest
0x00143511 395837454root66610485761
其中:
第一列就是共享内存的key;
第二列是共享内存的编号shmid;
第三列就是创建的用户owner;
第四列就是权限perms;
第五列为创建的大小bytes;
【linux共享内存命令 linux 共享内存大小】第六列为连接到共享内存的进程数nattach;
第七列是共享内存的状态status 。其中显示“dest”表示共享内存段已经被删除,但是还有用户在使用它,当该段内存的mode字段设置为SHM_DEST时就会显示“dest” 。当用户调用shmctl的IPC_RMID时,内存先查看多少个进程与这个内存关联着,如果关联数为0,就会销毁这段共享内存,否者设置这段内存的mod的mode位为SHM_DEST,如果所有进程都不用则删除这段共享内存 。
如何设置LINUX的共享内存我们可以修改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的共享内存首先先使用shmget建立一块共享内存,然后向该内存中写入数据并返回该共享内存shmid
使用另一个程序通过上一程序返回linux共享内存命令的shmid读该共享内存内linux共享内存命令的数据
建立共享内存并写入数据linux共享内存命令的程序
#include stdio.h
#include string.h
#include sys/ipc.h
#include sys/shm.h
#include stdlib.h
#include errno.h
void get_buf(char *buf)
{
int i=0;
while((buf[i]=getchar())!='\n'i1024)
i;
}
int main(void)
{
int shmid;
shmid=shmget(IPC_PRIVATE,sizeof(char)*1024,IPC_CREAT|0666);
if(shmid==-1)
{
perror("shmget");
}
char *buf;
if((int)(buf=shmat(shmid,NULL,0))==-1)
{
perror("shmat");
exit(1);
}
get_buf(buf);
printf("%d\n",shmid);
return 0;
}
读取数据linux共享内存命令的程序
#include stdio.h
#include sys/ipc.h
#include sys/shm.h
#include stdlib.h
int main(int argc,char **argv)
{
int shmid;
shmid=atoi(argv[1]);
char *buf;
if((int)(buf=shmat(shmid,NULL,0))==-1)
{
perror("shmat");
exit(1);
}
printf("%s\n",buf);
shmdt(buf);
return 0;
}
命令行linux共享内存命令的第一个参数设为第一个程序输出的数字

使用完以后可以使用
ipcrm -m 19562507
来删除该共享内存
共享内存 linux下怎么跑linux 共享内存实现
说起共享内存,一般来说会让人想起下面一些方法:
1、多线程 。线程之间的内存都是共享的 。更确切的说,属于同一进程的线程使用的是同一个地址空间,而不是在不同地址空间之间进行内存共享;
2、父子进程间的内存共享 。父进程以MAP_SHARED|MAP_ANONYMOUS选项mmap一块匿名内存,fork之后 , 其子孙进程之间就能共享这块内存 。这种共享内存由于受到进程父子关系的限制 , 一般较少使用;
3、mmap文件 。多个进程mmap到同一个文件,实际上就是大家在共享文件page cache中的内存 。不过文件牵涉到磁盘的读写 , 用来做共享内存显然十分笨重 , 所以就有了不跟磁盘扯上关系的内存文件,也就是我们这里要讨论的tmpfs和shmem;
tmpfs是一套虚拟的文件系统,在其中创建的文件都是基于内存的,机器重启即消失 。
shmem是一套ipc,通过相应的ipc系统调用shmget能够以指定key创建一块的共享内存 。需要使用这块内存的进程可以通过shmat系统调用来获得它 。
虽然是两套不同的接口,但是在内核里面的实现却是同一套 。shmem内部挂载了一个tmpfs分区(用户不可见),shmget就是在该分区下获取名为"SYSV${key}"的文件 。然后shmat就相当于mmap这个文件 。
所以我们接下来就把tmpfs和shmem当作同一个东西来讨论了 。
tmpfs/shmem是一个介于文件和匿名内存之间的东西 。
一方面,它具有文件的属性 , 能够像操作文件一样去操作它 。它有自己inode、有自己的page cache;
另一方面 , 它也有匿名内存的属性 。由于没有像磁盘这样的外部存储介质,内核在内存紧缺时不能简单的将page从它们的page cache中丢弃,而需要swap-out;(参阅《linux页面回收浅析》)
对tmpfs/shmem内存的读写,就是对page cache中相应位置的page所代表的内存进行读写 , 这一点跟普通的文件映射没有什么不同 。
如果进程地址空间的相应位置尚未映射 , 则会建立到page cache中相应page的映射;
如果page cache中的相应位置还没有分配page,则会分配一个 。当然,由于不存在磁盘上的源数据,新分配的page总是空的(特别的,通过read系统调用去读一个尚未分配page的位置时 , 并不会分配新的page , 而是共享ZERO_PAGE);
如果page cache中相应位置的page被回收了,则会先将其恢复;
对于第三个“如果”,tmpfs/shmem和普通文件的page回收及其恢复方式是不同的:
page回收时,跟普通文件的情况一样 , 内核会通过prio_tree反向映射找到映射这个page的每一个page table , 然后将其中对应的pte清空 。
不同之处是普通文件的page在确保与磁盘同步(如果page为脏的话需要刷回磁盘)之后就可以丢弃了 , 而对于tmpfs/shmem的page则需要进行swap-out 。
注意,匿名page在被swap-out时,并不是将映射它的pte清空,而是得在pte上填写相应的swap_entry,以便知道page被换出到哪里去,否则再需要这个page的时候就没法swap-in了 。
而tmpfs/shmem的page呢?page table中对应的pte被清空 , swap_entry会被存放在page cache的radix_tree的对应slot上 。
等下一次访问触发page fault时,page需要恢复 。
普通文件的page恢复跟page未分配时的情形一样,需要新分配page、然后根据映射的位置重新从磁盘读出相应的数据;
而tmpfs/shmem则是通过映射的位置找到radix_tree上对应的slot,从中得到swap_entry,从而进行swap-in,并将新的page放回page cache;
这里就有个问题了,在page cache的radix_tree的某个slot上 , 怎么知道里面存放着的是正常的page?还是swap-out后留下的swap_entry?
如果是swap_entry , 那么slot上的值将被加上RADIX_TREE_EXCEPTIONAL_ENTRY标记(值为2) 。swap_entry的值被左移两位后OR上RADIX_TREE_EXCEPTIONAL_ENTRY,填入slot 。
也就是说,如果${slot}RADIX_TREE_EXCEPTIONAL_ENTRY != 0,则它代表swap_entry , 且swap_entry的值是${slot}2;否则它代表page,${slot}就是指向page的指针,当然其值可能是NULL , 说明page尚未分配 。
那么显然 , page的地址值其末两位肯定是0,否则就可能跟RADIX_TREE_EXCEPTIONAL_ENTRY标记冲突了;而swap_entry的值最大只能是30bit或62bit(对应32位或64位机器) , 否则左移两位就溢出了 。
最后以一张图说明一下匿名page、文件映射page、tmpfs/shmem page的回收及恢复过程:
linux下什么是共享内存,怎么查看可以使用samba协议 。Samba是在Linux和UNIX系统上实现SMB协议linux共享内存命令的一个免费软件linux共享内存命令,由服务器及客户端程序构成 。SMB是一种在局域网上共享文件和打印机的一种通信协议,它为局域网内的不同计算机之间提供文件及打印机等资源的共享服务 。具体配置步骤如下linux共享内存命令:
步骤1linux共享内存命令:安装samba
sudo apt-get install samba samba-common-bin
步骤2:新建共享目录并设置权限
sudo mkdir /home/share
sudo chmod 777 /home/share
步骤3:修改配置文件
sudo nano /etc/samba/smb.conf
在smb.conf最后添加:
[share]
path = /home/share
browseable = yes
writable = yes
comment = smb share test
public = no#yes无需密码 no需要密码
步骤4:添加远程访问用户
sudo useradd smbuser
sudo smbpasswd -a smbuser
步骤5:重新启动服务
sudo service samba restart
对于windows操作系统,在资源管理器里输入\\Linux的IP地址,会提示输入上述步骤设置的用户名和密码,输入正确后即可访问分享内容 。
探讨一下 Linux 共享内存的 N 种方式 关于 Linux 共享内存,写得最好的应该是宋宝华的《世上最好的共享内存》 一文 。
本文可以说是对这篇文章的学习笔记,顺手练习了一下 rust libc ——shichaoyuan/learn_rust/linux-shmipc-demo
按照宋宝华的总结,当前有四种主流的共享内存方式:
前两种方式比较符合传统的用法,共享内存做为进程间通信的媒介 。
第三种方式更像是通过传递内存“句柄”进行数据传输 。
第四种方式是为设备间传递数据设计,避免内存拷贝,直接传递内存“句柄” 。
这里尝试了一下第二种和第三种方式 。
这套 API 应该是最普遍的 —— shm_openmmap,本质上来说Aeron也是用的这种方式(关于 Aeron 可以参考 我之前的文章 ) 。
看一下 glibc 中 shm_open 函数的实现就一清二楚了:
shm_open 函数就是在 /dev/shm 目录下建文件,该目录挂载为 tmpfs , 至于 tmpfs 可以简单理解为存储介质是内存的一种文件系统,更准确的理解可以参考官方文档tmpfs.txt。
然后通过 mmap 函数将 tmpfs 文件映射到用户空间就可以随意操作了 。
优点:
这种方式最大的优势在于共享的内存是有“实体”(也就是 tmpfs 中的文件)的,所以多个进程可以很容易通过文件名这个信息构建共享内存结构 , 特别适合把共享内存做为通信媒介的场景(例如Aeron ) 。
缺点:
如果非要找一个缺点的话,可能是,文件本身独立于进程的生命周期,在使用完毕后需要注意删除文件(仅仅 close 是不行的),否则会一直占用内存资源 。
memfd_create 函数的作用是创建一个匿名的文件 , 返回对应的 fd,这个文件当然不普通,它存活在内存中 。更准确的理解可以参考官方文档memfd_create(2)。
直观理解,memfd_create 与 shm_open 的作用是一样的,都是创建共享内存实体,只是 memfd_create 创建的实体是匿名的,这就带了一个问题:如何让其它进程获取到匿名的实体?shm_open 方式有具体的文件名,所以可以通过打开文件的方式获?。?那么对于匿名的文件怎么处理呢?
答案是:通过 Unix Domain Socket 传递 fd 。
rust 的 UDS 实现:
rust 在 std 中已经提供了 UDS 的实现,但是关于传递 fd 的send_vectored_with_ancillary函数还属于 nightly-only experimental API 阶段 。所以这里使用了一个三方 crate ——sendfd ,坦白说可以自己实现一下,使用 libc 构建好 SCM_RIGHTS 数据,sendmsg 出去即可,不过细节还是挺多,我这里就放弃了 。
这套 API 设计更灵活,直接拓展了我的思路 , 本来还是受限于Aeron的用法,如果在这套 API 的加持下,是否可以通过传递数据包内存块(fd)真正实现零拷贝呢?
优点:
灵活 。
缺点:

关于linux共享内存命令和linux 共享内存大小的介绍到此就结束了 , 不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站 。

    推荐阅读