找回密码
 立即注册
查看: 403|回复: 0

[linux] System V 共享内存

[复制链接]

19

主题

0

回帖

83

积分

注册会员

积分
83
发表于 2024-5-26 13:14:43 | 显示全部楼层 |阅读模式
本帖最后由 lavonXV 于 2024-5-26 13:16 编辑

共享内存是一种进程间通信(IPC)机制,允许多个进程共享一块内存区域,以实现数据的快速传递和共享。System V 共享内存是 UNIX 系统中一种经典的共享内存机制,具有广泛的应用。本文将详细介绍 System V 共享内存的概念、创建与使用方法,并提供示例代码以便更好地理解其实现和应用。


1. 概念与原理

共享内存是一种高效的进程间通信方式,允许多个进程直接访问同一块内存区域,避免了频繁的数据复制。System V 共享内存是基于 System V IPC(Inter-Process Communication)机制的一部分,通过系统调用进行操作。

1.1 关键概念

(1) 共享内存段:共享内存段是分配给多个进程共享的内存区域,每个共享内存段由一个唯一的标识符(shmid)进行标识。

(2) 键(key):键是用于创建或访问共享内存段的标识符,通过 `ftok` 函数生成。相同的键会得到相同的共享内存段标识符。

(3) 标志(flags):在创建共享内存段时,可以通过标志来设置权限和控制选项,如 `IPC_CREAT` 表示如果不存在则创建共享内存段。

2. 创建与使用

2.1 创建共享内存段

要创建一个共享内存段,需要使用 `shmget` 系统调用。


  1. int shmget(key_t key, size_t size, int shmflg);
复制代码



(1) `key`:共享内存段的键值,由 `ftok` 函数生成。
(2) `size`:共享内存段的大小(字节数)。
(3) `shmflg`:标志和权限,常用的标志包括 `IPC_CREAT` 和 `IPC_EXCL`。

示例代码:


  1. key_t key = ftok("path/to/file", 'R');
  2. int shmid = shmget(key, 1024, IPC_CREAT | 0666);
  3. if (shmid == -1) {
  4.     perror("shmget failed");
  5.     exit(1);
  6. }
复制代码



2.2 附加和分离共享内存段

创建共享内存段后,进程需要将其附加到自身的地址空间,这可以通过 `shmat` 系统调用实现。完成操作后,可以通过 `shmdt` 系统调用将其分离。


  1. void *shmat(int shmid, const void *shmaddr, int shmflg);
  2. int shmdt(const void *shmaddr);
复制代码



示例代码:


  1. void *shared_memory = shmat(shmid, NULL, 0);
  2. if (shared_memory == (void *)-1) {
  3.     perror("shmat failed");
  4.     exit(1);
  5. }

  6. // 使用共享内存...

  7. if (shmdt(shared_memory) == -1) {
  8.     perror("shmdt failed");
  9.     exit(1);
  10. }
复制代码


2.3 控制共享内存段

使用 `shmctl` 系统调用可以对共享内存段进行控制,如删除共享内存段、获取状态信息等。


  1. int shmctl(int shmid, int cmd, struct shmid_ds *buf);
复制代码



(1) `shmid`:共享内存段的标识符。
(2) `cmd`:控制命令,如 `IPC_RMID` 用于删除共享内存段。
(3) `buf`:存储状态信息的结构体指针。

示例代码:


  1. if (shmctl(shmid, IPC_RMID, NULL) == -1) {
  2.     perror("shmctl failed");
  3.     exit(1);
  4. }
复制代码



3. 示例应用

以下是一个示例程序,展示了如何使用 System V 共享内存在两个进程之间进行通信。

3.1 创建和写入共享内存段

创建一个共享内存段并写入数据。


  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/ipc.h>
  4. #include <sys/shm.h>
  5. #include <string.h>

  6. int main() {
  7.     key_t key = ftok("shmfile", 65);
  8.     int shmid = shmget(key, 1024, IPC_CREAT | 0666);
  9.     if (shmid == -1) {
  10.         perror("shmget failed");
  11.         exit(1);
  12.     }

  13.     char *str = (char *)shmat(shmid, NULL, 0);
  14.     if (str == (char *)-1) {
  15.         perror("shmat failed");
  16.         exit(1);
  17.     }

  18.     strcpy(str, "Hello, Shared Memory!");
  19.     printf("Data written to shared memory: %s\n", str);

  20.     if (shmdt(str) == -1) {
  21.         perror("shmdt failed");
  22.         exit(1);
  23.     }

  24.     return 0;
  25. }
复制代码


3.2 读取共享内存段

在另一个进程中读取共享内存段中的数据。


  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/ipc.h>
  4. #include <sys/shm.h>

  5. int main() {
  6.     key_t key = ftok("shmfile", 65);
  7.     int shmid = shmget(key, 1024, 0666);
  8.     if (shmid == -1) {
  9.         perror("shmget failed");
  10.         exit(1);
  11.     }

  12.     char *str = (char *)shmat(shmid, NULL, 0);
  13.     if (str == (char *)-1) {
  14.         perror("shmat failed");
  15.         exit(1);
  16.     }

  17.     printf("Data read from shared memory: %s\n", str);

  18.     if (shmdt(str) == -1) {
  19.         perror("shmdt failed");
  20.         exit(1);
  21.     }

  22.     if (shmctl(shmid, IPC_RMID, NULL) == -1) {
  23.         perror("shmctl failed");
  24.         exit(1);
  25.     }

  26.     return 0;
  27. }
复制代码


4. 总结

System V 共享内存是 UNIX 系统中一种高效的进程间通信机制,通过共享内存段,多个进程可以直接读写同一块内存区域。本文详细介绍了共享内存的概念、创建与使用方法,并提供了示例代码,帮助读者更好地理解和应用这一技术。希望这些内容能帮助您在实际项目中更高效地实现进程间通信。

资讯 | 优惠 | 测评 | 技术
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

联系站长|Archiver|手机版|小黑屋|主机论坛

GMT+8, 2025-4-5 02:29 , Processed in 0.071980 second(s), 24 queries .

Powered by 主机论坛 HostSsss.Com

HostSsss.Com

快速回复 返回顶部 返回列表