共享内存是一种操作系统提供的机制,用于实现多个进程之间共享数据的方式。在共享内存中,多个进程可以访问同一块物理内存区域,从而实现数据的共享和通信,而不需要进行显式的数据拷贝或进程间的消息传递。
共享内存的基本原理是将一块内存区域映射到多个进程的地址空间中,使得这些进程可以直接访问该内存区域。这种共享的内存区域被称为共享内存段。多个进程可以通过读写共享内存段来实现数据的共享和交互。
使用共享内存可以提高数据访问和传输的效率,因为数据直接存储在物理内存中,进程可以直接读写内存,而不需要进行数据的拷贝或消息的传递。然而,由于多个进程可以同时访问共享内存,因此需要采取适当的同步机制,如锁或信号量,来保证数据的一致性和避免竞态条件。
int shmget (key_t __key, size_t __size, int __shmflg)
key:共享内存的键值,可以理解为共享内存的唯一性标记
size:共享内存的大小
shmflag:创建进程和其他进程的读写权限标识
返回值:响应的共享内存的标识符,失败返回-1
void *shmat (int __shmid, const void *__shmaddr, int __shmflg)
shm_id:共享内存标识符
shm_addr:指定共享内存连接到当前进程的地址;通常为0,表示由系统来选择
shmflag:标志位
返回值:指向共享内存第一个字节的指针,失败返回-1
int shmdt (const void *__shmaddr)
int shmctl (int __shmid, int __cmd, struct shmid_ds *__buf)
和信号量的semctl函数类似,控制共享内存
shm_id:共享内存标识符
command:有三个值:
IPC_STAT:获取共享内存的状态信息,包括共享内存的大小、创建时间、最后访问时间、进程ID等。
IPC_SET:设置共享内存的状态信息,例如修改共享内存的权限、最后访问时间等。
IPC_RMID:删除共享内存段,释放分配的内存资源。
需要注意的是,shmctl函数的第三个参数__buf是一个指向shmid_ds结构体的指针,用于传递共享内存的状态信息。在使用IPC_STAT命令时,__buf指向的结构体将被填充共享内存的状态信息。在使用IPC_SET命令时,__buf指向的结构体应该包含要设置的共享内存状态信息。在使用IPC_RMID命令时,__buf可以为NULL。
除了上述常用的命令,还有其他一些命令可供使用,例如:
IPC_INFO:获取系统中共享内存的状态信息,包括共享内存的总数、使用的共享内存段数量、共享内存的最大大小等。
SHM_LOCK:锁定共享内存,阻止其被交换到磁盘上。
SHM_UNLOCK:解锁共享内存,允许其被交换到磁盘上
#include
#include
#include
#include
#include
#include
using namespace std;
int main() {
int shmId; // 共享内存ID号
char *shmPtr; // 指向共享内存的指针
key_t shmKey; // 创建共享内存的键值
size_t shmSize; // 共享内存的大小
shmKey = ftok(".", 'a'); // 获取用于创建共享内存的键值
shmSize = getpagesize(); // 获取系统内存页的大小
// 创建共享内存
shmId = shmget(shmKey, shmSize, IPC_CREAT | 0666);
if (shmId < 0) {
cerr << "Error: shmget() failed" << endl;
exit(1);
}
// 映射共享内存到进程的地址空间
shmPtr = (char *) shmat(shmId, NULL, 0);
if (shmPtr == (char *) -1) {
cerr << "Error: shmat() failed" << endl;
exit(1);
}
// 数据写入共享内存
strcpy(shmPtr, "Hello, shared memory,this is first write data!");
// 读取共享内存中的数据
cout << "Shared memory content first read:\n " << shmPtr << endl;
//重新写入共享内存
strcpy(shmPtr, "Hello, shared memory,this is second write data!");
// 读取共享内存中的数据
cout << "Shared memory content again:\n\n" << shmPtr << endl;
//获取系统中共享内存的状态信息
struct shminfo shm_info;
shmctl(shmId, IPC_INFO, (struct shmid_ds*)&shm_info);
cout << "共享内存总数: " << shm_info.shmmni << endl;
cout << "已使用的共享内存段数量: " << shm_info.shmseg << endl;
cout << "共享内存的最大大小: " << shm_info.shmmax << endl;
// 分离共享内存
if (shmdt(shmPtr) < 0) {
cerr << "Error: shmdt() failed" << endl;
exit(1);
}
// 删除共享内存
if (shmctl(shmId, IPC_RMID, NULL) < 0) {
cerr << "Error: shmctl() failed" << endl;
exit(1);
}
return 0;
}
共享内存是多个进程之间共享数据的一种方式,主要有以下场景:
进程间通信:多个进程之间需要共享一些数据或对象,例如操作系统为进程间的通信提供的缓冲区就是使用共享内存实现的。
高性能计算:在高性能计算中,多个进程需要访问共享的数据结构,例如矩阵运算等,使用共享内存可以避免数据拷贝和通信的开销,提高程序性能。
大型数据库:大型数据库需要频繁地进行数据访问和更新,使用共享内存可以提高数据访问效率,缩短数据读写时间。
多进程服务器:多进程服务器需要共享一些全局数据,例如监听端口号、连接池、缓冲区等。
总之,共享内存是在多个进程之间共享数据的重要方式之一。在需要大量数据传输和频繁访问数据的场景中,使用共享内存可以提高程序效率和性能。但是,需要注意使用锁或者其他同步机制来保证数据的一致性和可靠性。