进程间通信(3)-共享内存

Linux 中的共享内存是一种进程间通信的机制,允许多个进程共享同一块物理内存区域。共享内存是一种高效的 IPC(进程间通信)方式,适用于需要频繁交换数据的情况,因为它不涉及数据的复制,而是直接在内存中进行读写操作。
在 Linux 中,共享内存的使用通常涉及以下几个步骤:
  1. 创建共享内存段:使用 shmget 函数创建一个共享内存段,为其指定大小和权限等参数。
  2. 将共享内存连接到进程地址空间:使用 shmat 函数将共享内存段连接到当前进程的地址空间中,从而使得进程可以直接访问共享内存中的数据。
  3. 进行数据读写操作:在共享内存中进行数据的读写操作,可以通过指针直接访问共享内存中的数据。
  4. 分离共享内存:使用 shmdt 函数将共享内存从当前进程的地址空间中分离。
  5. 删除共享内存段(可选):使用 shmctl 函数删除共享内存段,释放资源。
 

共享内存的相关函数:

享内存的相关函数:
shmget(key_t key, size_t size, int shmflg):创建或获取一个共享内存标识符。
key:共享内存的键值。
size:共享内存的大小。
shmflg:标志位,指定共享内存的权限和行为,比如 IPC_CREAT 表示如果共享内存不存在则创建它。


shmat(int shmid, const void *shmaddr, int shmflg):将共享内存段连接到进程的地址空间。
shmid:共享内存标识符。
shmaddr:指定要将共享内存连接到进程地址空间的地址,通常设置为 NULL,表示由系统选择合适的地址。
shmflg:连接标志,通常为 0。


shmdt(const void *shmaddr):将共享内存段从进程的地址空间中分离。
shmaddr:指向共享内存段的指针。


shmctl(int shmid, int cmd, struct shmid_ds *buf):控制共享内存的状态。
shmid:共享内存标识符。
cmd:控制命令,比如 IPC_RMID 表示删除共享内存。
buf:指向 shmid_ds 结构的指针,用于获取或设置共享内存的状态信息。

 

写入共享内存shm1.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>

#define SHM_SIZE 1024  // 共享内存大小
#define SHM_KEY 12345678   // 共享内存键值

int main() {
    int shmid;  // 共享内存标识符

    // 创建共享内存段
    if ((shmid = shmget(SHM_KEY, SHM_SIZE, IPC_CREAT | 0666)) < 0) {  // SHM_KEY可以通过ftok获得,此处直接定义为12345678
        perror("shmget");
        exit(EXIT_FAILURE);
    }

    // 将共享内存段连接到当前进程的地址空间
    char *shmaddr;
    if ((shmaddr = shmat(shmid, NULL, 0)) == (char *) -1) {
        perror("shmat");
        exit(EXIT_FAILURE);
    }

    // 向共享内存写入数据
    strcpy(shmaddr, "Hello, shared memory!");

    // 分离共享内存段
    if (shmdt(shmaddr) == -1) {
        perror("shmdt");
        exit(EXIT_FAILURE);
    }

    return 0;
}
 

读取共享内存shm2.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#define SHM_SIZE 1024  // 共享内存大小
#define SHM_KEY 12345678   // 共享内存键值

int main() {
    int shmid;  // 共享内存标识符

    // 获取共享内存段
    if ((shmid = shmget(SHM_KEY, SHM_SIZE, 0666)) < 0) {  // SHM_KEY可以通过ftok获得,此处直接定义12345678
        perror("shmget");
        exit(EXIT_FAILURE);
    }

    // 将共享内存段连接到当前进程的地址空间
    char *shmaddr;
    if ((shmaddr = shmat(shmid, NULL, 0)) == (char *) -1) {
        perror("shmat");
        exit(EXIT_FAILURE);
    }

    // 从共享内存读取数据并打印
    printf("Data read from shared memory: %s\n", shmaddr);

    // 分离共享内存段
    if (shmdt(shmaddr) == -1) {
        perror("shmdt");
        exit(EXIT_FAILURE);
    }

    return 0;
}
 

执行结果如下:

0
 
 
 
 
 
posted @ 2024-04-04 06:53  lethe1203  阅读(24)  评论(0编辑  收藏  举报