当前位置:首页 > 内存 > 正文

linux共享内存参数(linux共享内存命令)

  • 内存
  • 2024-06-09 20:53:15
  • 8651

一、如何设置linux的共享内存

Linux中设置共享内存的方法有很多种,以下是常用的方法:

使用shmget()函数创建一部分共享内存,并且可以指定大小。共享内存标识符。

使用shmat()函数将共享内存连接到进程地址空间并返回指向共享内存的指针。

使用shmdt()函数断开与共享内存的连接。

使用shmctl()函数删除共享内存。

具体实现请参考以下代码示例:

#include

#include

#include

intmain(){

//1.创建共享内存

intshmid=shmget(IPC_PRIVATE),100,0666|IPC_CREAT);

if(shmid<0){

perror("shmgeterror");

return1;

//2.连接共享内存

void*shm=shmat(shmid,NULL,0);

if(shm==(void*)-1){

perror("shmaterror");

return1;

}

//使用共享内存

//...

//3.断开连接

if(shmdt(shm)<0){

perror("shmdterror");

return1;

}

//4.删除共享内存

if(shmctl(shmid,IPC_RMID,0)<0){

perror("shmctlerror");

return1;

}

return0;

这是一个简单的例子,我们创建一个100字节的共享内存并使用shmget(),shmat()、shmdt()、shmctl()四个函数创建、连接、分离和删除共享内存。

在实际应用中,我们需要根据需要调整共享内存的大小,并在使用共享内存时进行相应的同步和互斥操作,以保证数据安全。

需要注意的是,在使用共享内存时,我们需要保证所有进程退出后共享内存能够被释放。这可以通过删除父进程中的共享内存

来实现。此外,还必须考虑程序中的异常处理。如果程序运行时出现异常,必须及时释放占用的共享内存,避免资源浪费。

另外提醒一点,共享内存是一种高级的IPC(进程间通信)机制,要谨慎使用,避免出现数据争用、死锁等问题。


二、共享内存的参数详解

cmd的值含义
IPC_STAT:取出shm_id指向的内存共享段的shmid_ds结构体,并为参数buf指向的结构体赋值
IPC_SET:使用该结构体buf指向的sh_mid段的相关结构体进行赋值。它仅适用于以下域:shm_perm.
uidshm_和shm_。请注意,该命令只能由满足以下条件的进程请求:
1.进程的用户ID等于shm_或等于shm_
2。超级用户特权进程
IPC_RMID:删除shm_id指向的共享内存段。只有当shmid_ds结构体的shm_nattch字段为零时,删除命令才会真正被执行。否则,该段将不会被删除。请注意该命令的请求规则。与IPC_SET命令相同
SHM_LOCK:锁定内存中的共享内存段,该命令只能由超级用户请求
SHM_UNLOCK:解锁共享内存段,该命令只能由超级用户请求user
Used函数shmat将现有的共享内存段连接到进程空间。其函数原型如下:
#include
void*shmat(intshm_id,constvoid*addr,intflag);
函数中参数shm_id指定要引入的共享内存,参数addr和flag组合表示要引入的地址值。通常只有两种用途。Addr为0,表示内核确定第一个可以引入的位置。addr非零,且flag中指定了SHM_RND,则本节引入到addr指向的位置(不推荐此操作,因为应用程序不会只运行在一种硬件上。为了通用性,程序中,建议使用第一种方法),要引入的方法可以在flag参数中指定(读写模式规范)。
%注意:函数执行成功时返回值为实际传入的地址,失败时返回-1。shmat函数成功执行将使shm_id段的shmid_ds结构体的shm_nattch计数器的值加1。
当对共享内存段的操作完成后,应该调用shmdt函数,即从当前进程空间中删除指定的共享内存段。函数原型如下:
#include
intshmdt(void*addr);
参数addr为调用shmat函数的返回值。函数成功返回0,并将共享内存的shmid_ds结构体的shm_nattch计数器减1,失败则返回-1。
下面的例子演示了操作共享内存段的过程。程序一开始首先检测用户是否有输入,如果出现错误,则打印该命令的帮助。接下来从命令行读取要引入的共享内存ID,使用shmat函数引入共享内存,在分离内存之前休眠3秒,方便查看系统IPC状态。
(1)在vi编辑器中编辑程序如下:
程序列表14-9opr_shm.c操作共享内存段
#include
#include
#include
#include
#include
intmain(intargc,char*argv[])
{
intshm_id;
char*shm_buf;
if(argc!=2){/*命令行参数错误*/
printf(USAGE:atshm);/*打印帮助信息*/
exit(1);
}
shm_id=atoi(argv[1]);/*获取import共享内存段*/
/*引入共享内存段,内核选择引入位置*/
if((shm_buf=shmat(shm_id,0,0))<(char*)0){
perror(shmat);
exit(1);
}
printf(segmentattachedat%p\n,shm_buf);/*输出的位置import*/
system(ipcs-m);
sleep(3);/*sleep*/
if((shmdt(shm_buf))<0){/*与导入的共享内存段*/
perror(shmdt);
exit(1);
}
printf(segmentdetached\n);
system(ipcs-m);/*再次检查系统IPC状态*/
exit(0);
}
(2)在shell中编译程序如下:
$gccopr_shm.c-oopr_shm
(3)在shell中运行程序如下:
$./opr_shm2752516
segmentattachedat0xb7f29000
------SharedMemorySegments--------
keyshmidownerpermsbytesnattchstatus
0x000root6003932162dest
0x00000root66640960
0x0056a4d52686978root6004881
0x0056a4d62719747root6001310721
0x00000root66640961
segmentdetached
-------共享内存段--------
keyshmidownerpermsbytesnattchstatus
0x0000065root6003932162dest
0x000209root66640960
0x0056a4d52686978root6004881
0x0056a4d62719747root6001310721
0x000002516root66640960
上面的程序中,读取共享内存ID从命令行引入,使用shmat函数引入。内存到当前进程空间。注意,使用shmat函数时,将参数addr的值设置为0,这意味着内核决定共享内存在当前进程中的位置。由于在编程过程中,很少会针对特定的硬件或系统进行编程,因此内核决定引入位置,推荐使用shmat。导入后,使用shell命令ipcs-m显示当前系统IPC状态。可以看出,输出信息中的nattch字段就是共享内存的参考值。最后使用shmdt函数分离共享内存并打印系统IPC状态。


三、如何设置LINUX的共享内存我们可以修改内核参数shmmax,使SGA存在于共享内存段中。
这个目的可以通过修改/proc/sys/kernel/shmmax参数来实现。
【[root@neirongroot]#echo1073741824>/proc/sys/kernel/shmmax
【[root@nairongroot]#more/proc/sys/kernel/shmmax
<1073741824这里设置为1G。
修改shmmax文件,系统重启后会重置。通过修改/etc/可以使更改永久化。
将以下行=1073741824添加到文件中。此更改将在系统重新启动后生效。
1.设置SHMMAX
SHMMAX
该参数定义共享内存段的最大大小(以字节为单位)。安装SHMMAX时,请记住SGA的大小必须适合共享内存段。SHMMAX设置不足可能会导致以下问题:
ORA-27123:unabletoattachtosharedmemorysegment
您可以通过执行以下命令来确定SHMMAX的值:
#cat/proc/sys/kernel/shmmax
33554432
SHMMAX的默认值为32MB。我通常使用以下方法之一将SHMMAX参数设置为2GB:
通过直接更改/proc文件系统,可以更改SHMMAX的默认设置,而无需重新启动机器。我使用的方法是在/etc/启动文件中放入如下命令:
​#>echo"2147483648">/proc/sys/kernel/shmmax
​也可以使用sysctl命令更改SHMMAX的值:
#=2147483648
最后,您可以通过将此内核参数插入到/etc引导文件/中来使此更改永久化:
#echo"=2147483648">>/etc/
 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的默认设置对于我们的Oracle9iRAC安装来说应该足够了。
注意:i386平台上的RedHatLinux页面大小为4096字节。但是,您可以使用大页面,它支持配置更大的内存页面大小。