内存Linux下查看、使用共享内存

1. Linux下的共享内存介绍

共享内存是一种进程间通信的方式,可以实现多个进程之间对同一块内存地址的直接访问。在Linux中,共享内存是一种高速的进程间通信方式,它不需要复制数据,进程可以直接读写共享内存,大大提高了程序的效率。

共享内存的使用需要先创建一块共享内存区域,然后进程可以通过访问这块共享内存区域来实现数据共享。在Linux系统中,我们可以使用系统调用shmget、shmat、shmdt和shmctl来创建、连接、断开和删除共享内存。

2. 查看共享内存信息

2.1. 使用ipcs命令

ipcs命令可以用来查看共享内存的信息,包括共享内存的标识符、键值、尺寸、创建者、连接数等。使用以下命令可以查看当前系统中的共享内存:

ipcs -m

该命令会列出系统中所有共享内存的信息,我们可以根据需求查找我们关心的共享内存。

例如,以下是一个示例输出:

T ID KEY MODE OWNER GROUP CPID LPID CUID CGID NATTCH SEGSZ CPUSZ GMTIME

m 32768 0x12345678 --rw-rw-rw- user1 group1 12345 12345 user1 group1 1 4096 4096 Fri Mar 1 15:00:00 2023

m 32769 0x87654321 --rw-rw-rw- user2 group2 54321 54321 user2 group2 2 8192 8192 Fri Mar 1 16:00:00 2023

通过ipcs命令,我们可以看到共享内存的ID、键值、权限信息、创建者、连接数、共享内存大小等。

2.2. 使用proc文件系统

Linux提供了proc文件系统,通过读取/proc/sysvipc/shm文件来获取共享内存信息。可以使用以下命令查看共享内存:

cat /proc/sysvipc/shm

此命令会显示共享内存的相关信息,例如:

key shmid perms size cpid lpid nattch status

0x12345678 32768 666 4096 12345 12345 1 dest (deleted)

0x87654321 32769 666 8192 54321 54321 2 dest

通过读取/proc/sysvipc/shm文件,我们可以获取到共享内存的键值、共享内存ID、权限、大小、创建者进程ID、连接进程ID等信息。

3. 使用共享内存

3.1. 创建共享内存

在Linux中,我们可以使用shmget系统调用来创建共享内存。shmget函数的原型如下:

int shmget(key_t key, size_t size, int shmflg);

其中,key是共享内存的键值,可以使用ftok函数生成;size是共享内存的大小;shmflg是共享内存的权限标志,可以使用IPC_CREAT标志来创建新共享内存。

示例代码如下:

#include <stdio.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#define SHM_SIZE 4096

int main() {

key_t key = ftok("shmfile", 'A'); // 生成键值

int shmid = shmget(key, SHM_SIZE, IPC_CREAT | 0666); // 创建共享内存

if (shmid == -1) {

perror("shmget");

return -1;

}

printf("Shared memory ID: %d\n", shmid);

return 0;

}

上述代码通过ftok函数生成键值,并使用shmget创建一个大小为4096字节的共享内存。如果创建成功,shmget函数会返回共享内存ID,我们可以通过该ID来访问共享内存。

3.2. 连接共享内存

在Linux中,我们可以使用shmat系统调用来连接共享内存。shmat函数的原型如下:

void *shmat(int shmid, const void *shmaddr, int shmflg);

其中,shmid是共享内存的ID;shmaddr是共享内存连接的地址,一般为NULL,让系统选择合适的地址;shmflg是共享内存访问标志,一般为0。

示例代码如下:

#include <stdio.h>

#include <sys/ipc.h>

#include <sys/shm.h>

int main() {

key_t key = ftok("shmfile", 'A'); // 生成键值

int shmid = shmget(key, SHM_SIZE, 0666); // 创建共享内存

if (shmid == -1) {

perror("shmget");

return -1;

}

void *shmaddr = shmat(shmid, NULL, 0); // 连接共享内存

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

perror("shmat");

return -1;

}

printf("Shared memory address: %p\n", shmaddr);

return 0;

}

上述代码中,我们使用shmat函数连接了先前创建的共享内存,并通过打印共享内存地址来验证连接成功。

3.3. 使用共享内存

在连接共享内存后,我们可以通过指针来访问共享内存的数据。需要注意的是,共享内存的指针指向的是原始数据,因此必须自己处理数据的格式等问题。

以下是一个简单的示例,演示了一个进程将数据写入共享内存,另一个进程读取并打印共享内存中的数据:

#include <string.h>

#include <stdio.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#define SHM_SIZE 4096

typedef struct {

char name[20];

int age;

} Person;

int main() {

key_t key = ftok("shmfile", 'A'); // 生成键值

int shmid = shmget(key, SHM_SIZE, 0666); // 创建共享内存

if (shmid == -1) {

perror("shmget");

return -1;

}

void *shmaddr = shmat(shmid, NULL, 0); // 连接共享内存

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

perror("shmat");

return -1;

}

Person *person = (Person *)shmaddr; // 指针转换

strcpy(person->name, "Alice"); // 写入数据

person->age = 20;

// 读取数据

printf("Name: %s\n", person->name);

printf("Age: %d\n", person->age);

shmdt(shmaddr); // 断开共享内存连接

return 0;

}

上述代码中,我们定义了一个Person结构体,然后将共享内存指针转换为Person类型的指针,实现对共享内存数据的写入和读取。

4. 删除共享内存

在使用完共享内存后,我们需要手动删除共享内存以释放资源。在Linux中,可以使用shmctl系统调用来删除共享内存。shmctl函数的原型如下:

int shmctl(int shmid, int cmd, struct shmid_ds *buf);

其中,shmid是共享内存的ID;cmd是需要执行的操作,可以使用IPC_RMID来删除共享内存;buf是shmid_ds结构的指针,用于获取共享内存的信息,一般为NULL。

示例代码如下:

#include <stdio.h>

#include <sys/ipc.h>

#include <sys/shm.h>

int main() {

key_t key = ftok("shmfile", 'A'); // 生成键值

int shmid = shmget(key, SHM_SIZE, 0666); // 创建共享内存

if (shmid == -1) {

perror("shmget");

return -1;

}

if (shmctl(shmid, IPC_RMID, NULL) == -1) { // 删除共享内存

perror("shmctl");

return -1;

}

printf("Shared memory removed\n");

return 0;

}

上述代码中,我们使用shmctl函数删除了先前创建的共享内存,并通过打印信息来验证删除成功。

5. 总结

共享内存是Linux下一种高速的进程间通信方式,可以实现多个进程之间对同一块内存地址的直接访问。本文介绍了如何在Linux下查看、使用和删除共享内存的方法,包括使用ipcs命令和读取/proc/sysvipc/shm文件查看共享内存信息,使用shmget创建共享内存,使用shmat连接共享内存,以及使用shmctl删除共享内存。通过本文的介绍,读者可以了解到共享内存的基本使用方法,并在实际开发中灵活运用。

操作系统标签