网站维护是什么,青岛李沧建设局网站,网络编程技术期末考试,天津建设工程信息网 官网首页文章目录 引言什么是共享内存System V 共享内存 API 引入1. shmget2. shmat3. shmdt4. shmctl5. 结构体 shmid_ds 开始实操注意 结束 今天的你有没有前进一小步呢 ——家驹(StrangeHead) 引言
那么共享内存#xff0c;我们如何去使用他呢#xff0c;先来听笔者啰嗦一段话吧… 文章目录 引言什么是共享内存System V 共享内存 API 引入1. shmget2. shmat3. shmdt4. shmctl5. 结构体 shmid_ds 开始实操注意 结束 今天的你有没有前进一小步呢 ——家驹(StrangeHead) 引言
那么共享内存我们如何去使用他呢先来听笔者啰嗦一段话吧有个整体的概念。
共享内存听这个名字就像已经知道他是什么东东了既然我们现在学习的的Linux进程之间的通讯所以这个共享内存肯定也离不开通讯的功能是的他是IPC中的重要一员成为高手也是必须要掌握的。
对于共享内存Linux中共享内存的两种主要实现方式System V和POSIX。没错又是两套API关于这两套API笔者就教大家如何使用System V吧因为POSIX感觉并不常用读者朋友们有兴趣可以自己学一学。
那么进入正题。
什么是共享内存
他总体的作用就是在Linux当中开辟一段内存空间使得两个进程可以同时访问是的就是这么简单
具体操作可以具象为操作一个文件毕竟Linux中一切皆是文件呢
open一个文件没有就创建他 我可以使用read读取他也可以使用write去修改他。 当然这个文件也可以让所有进程看到并操作。 这样说我们理所当然的就学会了共享内存我们对于一个文件的操作其实就是对共享内存进行操作
那么他有什么API呢总不能和文件的open等等的API冲突吧肯定也有自己的优势方便之处吧来看一下吧。
特性共享内存文件操作速度直接在内存中操作速度快涉及磁盘 I/O速度较慢内存共享多个进程可以直接共享数据每个进程通常创建自己的文件副本资源利用内存使用更加高效避免冗余每个进程可能会重复打开和关闭文件数据一致性直接访问最新数据避免不一致性可能需要额外同步机制保证一致性适用场景高频率、大量数据交换持久化存储、日志记录等复杂性需要管理访问权限和同步机制操作相对简单易于理解系统调用数量包含 shmget, shmat, shmdt, shmctl包含 open, read, write, close
共享内存 更适合需要快速、高效的数据交换的场景尤其是涉及到大量数据的实时处理。文件操作 更适合需要持久化存储和简单文件操作的场景。 查看和删除共享内存拓展 你可以使用 ipcs -m 查看共享内存段并通过 ipcrm 删除它 System V 共享内存 API 引入
总之就是下面这一坨了
int shmget(key_t key, size_t size, int shmflg); // 创建/获取共享内存
void *shmat(int shmid, const void *shmaddr, int shmflg); // 附加到进程空间
int shmdt(const void *shmaddr); // 分离共享内存
int shmctl(int shmid, int cmd, struct shmid_ds *buf); // 控制操作我们依次介绍他。大致看看即可通过实例学习不了解可以回来继续复习。 1. shmget
功能创建一个新的共享内存段或者获取一个已经存在的共享内存段的标识符。
原型
int shmget(key_t key, size_t size, int shmflg);参数
key用于标识共享内存段的键。可以通过 ftok 函数生成一个唯一的键。size共享内存段的大小以字节为单位。如果要创建新的共享内存段此值必须大于 0。shmflg控制标志可以包括以下选项 IPC_CREAT如果指定的共享内存段不存在则创建它。IPC_EXCL与 IPC_CREAT 一起使用如果共享内存段已经存在则调用失败。权限标志如 0666指定谁可以读/写共享内存段。
返回值成功时返回共享内存段的标识符非负整数失败时返回 -1并设置 errno。
示例
int shm_id shmget(IPC_PRIVATE, 1024, IPC_CREAT | 0666);2. shmat
功能将共享内存段附加到调用进程的地址空间。
原型
void* shmat(int shm_id, const void* shmaddr, int shmflg);参数
shm_id通过 shmget 返回的共享内存段标识符。shmaddr希望共享内存段附加到的地址。通常可以设置为 NULL由系统自动选择。shmflg控制标志通常设置为 0。
返回值成功时返回指向共享内存段的指针失败时返回 (void*) -1并设置 errno。
示例
char* shm_ptr (char*) shmat(shm_id, NULL, 0);3. shmdt
功能将共享内存段从调用进程的地址空间分离。
原型
int shmdt(const void* shmaddr);参数
shmaddr指向之前通过 shmat 返回的共享内存指针。
返回值成功时返回 0失败时返回 -1并设置 errno。
示例
if (shmdt(shm_ptr) -1) {perror(shmdt failed);
}4. shmctl
功能控制共享内存段的操作包括查询、修改和删除。
原型
int shmctl(int shm_id, int cmd, struct shmid_ds* buf);参数
shm_id共享内存段的标识符。cmd控制命令可以是以下之一 IPC_STAT填充 shmid_ds 结构体用于获取共享内存信息。IPC_RMID标记共享内存段为待删除。IPC_SET修改共享内存段的权限和其他信息需要提供相应的 shmid_ds 结构体。IPC_INFO获取系统共享内存的信息通常是系统级的。 buf指向 shmid_ds 结构体的指针用于输入/输出的控制信息。
返回值成功时返回 0失败时返回 -1并设置 errno。
示例删除共享内存段
if (shmctl(shm_id, IPC_RMID, NULL) -1) {perror(shmctl IPC_RMID failed);
}5. 结构体 shmid_ds
用于描述共享内存段的状态包括以下字段
struct shmid_ds {struct ipc_perm shm_perm; // 共享内存的权限size_t shm_segsz; // 共享内存段的大小time_t shm_atime; // 最后附加时间time_t shm_dtime; // 最后分离时间time_t shm_ctime; // 最后控制时间unsigned short shm_cpid; // 创建该共享内存段的进程 IDunsigned short shm_lpid; // 最后操作该共享内存段的进程 IDshort shm_nattch; // 当前附加到该共享内存段的进程数
};开始实操
通过上述 API可以有效地创建和管理共享内存段从而实现进程间的高效通信。在使用共享内存时务必注意同步问题以避免数据竞争和不一致性。对于更复杂的应用可能需要结合其他 IPC 机制如信号量来实现更可靠的进程间通信。
我们先简单的利用API来实现两个程序一个写入一个读取。
写入进程
#include sys/ipc.h
#include sys/shm.h#define SHM_SIZE 1024int main() {key_t key ftok(shmfile, 65);int shmid shmget(key, SHM_SIZE, 0666|IPC_CREAT);char *str (char*) shmat(shmid, NULL, 0);sprintf(str, Hello from PID %d, getpid());shmdt(str);return 0;
}读取进程
// ...头文件同上
int main() {key_t key ftok(shmfile, 65);int shmid shmget(key, SHM_SIZE, 0666);char *str (char*) shmat(shmid, NULL, 0);printf(Received: %s\n, str);shmdt(str);shmctl(shmid, IPC_RMID, NULL); // 删除共享段return 0;
}这里仅仅做了这样一个小实验随着日后技术的提升不断迭代希望读者可以灵活应用这里没有加入其它IPC同步机制实际使用对于共享内存的访问是要做保护机制的仅仅让读者快速掌握他如何使用。 监控与调试技巧 使用ipcs -m查看System V共享段 通过lsof /dev/shm检查POSIX对象 分析/proc/sysvipc/shm获取详细信息 使用strace跟踪shm相关系统调用 注意
同步机制必须实现以下之一
使用共享内存必须必须使用同步机制避免同时访问或者操作造成数据错乱或者死机 信号量semaphore 互斥锁pthread_mutex需配置进程共享属性 文件锁fcntl
生命周期管理 System V需主动调用shmctl(IPC_RMID) POSIX引用计数归零后自动删除
安全配置 严格设置权限位如0600 避免使用可预测的IPC键值 及时清理未使用的共享段
性能调优 使用大页内存Hugepages 对齐内存访问边界 避免频繁attach/detach操作
结束
浅浅的总结一下吧这节我们学到了System V共享内存以及他的一些核心API的使用知道了他是什么东西。虽然操作文件的大致流程上没有俩样。但是使用上还是更具实际情况选择哦并且给了两段小程序来帮助理解再次提醒实际情况要做同步机制保护。 好了本文就到这里了让我们每天进步一小步吧