企业网站内容运营方案案例,做注册会员和购物的网站需要什么,去视频网站做编辑,网站怎么做第二个页面阅读导航 引言一、system V的概念二、共享内存(1) 概念(2) 共享内存示意图(3) 共享内存数据结构 三、共享内存的使用1. 共享内存的使用步骤#xff08;1#xff09;包含头文件#xff08;2#xff09;获取键值#xff08;ftok函数#xff09;#xff08;3#xff09;创… 阅读导航 引言一、system V的概念二、共享内存(1) 概念(2) 共享内存示意图(3) 共享内存数据结构 三、共享内存的使用1. 共享内存的使用步骤1包含头文件2获取键值ftok函数3创建共享内存段shmget函数4将共享内存连接到当前进程的地址空间shmat函数5访问共享内存6分离共享内存shmdt函数 2. 共享内存的使用示例进程1创建共享内存并写入数据进程2连接共享内存并读取数据 四、共享内存的优缺点温馨提示 引言
在多进程编程中进程间通信IPC是一项关键技术它使得不同的进程能够相互交换数据和协调行为。而在众多的IPC机制中System V共享内存是一种高效且强大的通信方式。通过使用共享内存我们可以将数据从一个进程快速地传递给另一个进程避免了复制数据的开销提高了数据传输的效率。同时由于共享内存是在进程之间共享的内存区域进程可以直接在该内存区域进行读写操作从而实现了高效的数据交换。本文将深入探讨System V共享内存的原理、使用方法以及相关函数并结合实际场景介绍如何利用共享内存进行进程间通信。无论您是初学者还是有经验的开发者本文都将为您提供全面的指导帮助您更好地掌握System V共享内存并应用于您的项目中。让我们一起深入研究进程间通信的精髓开启高效、协同的多进程编程之旅吧
一、system V的概念
System V是指ATT公司开发的一系列UNIX操作系统版本它是UNIX历史上最著名和广泛使用的一个分支。System V在1979年发布其名称中的“V”代表着罗马数字5表明它是UNIX的第五个主要版本。
System V引入了许多重要的功能和概念其中之一就是System V IPC进程间通信。System V IPC是一组用于在不同进程之间传递数据和协调行为的机制。它包括三种主要的IPC机制共享内存Shared Memory、消息队列Message Queues和信号量Semaphores
二、共享内存
(1) 概念
在Linux系统中System V共享内存是一种用于进程间通信的机制它允许多个进程访问同一块物理内存从而实现数据共享。
共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间这些进程间数据传递不再涉及到内核换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据
(2) 共享内存示意图 (3) 共享内存数据结构
struct shmid_ds {struct ipc_perm shm_perm; /* operation perms */int shm_segsz; /* size of segment (bytes) */__kernel_time_t shm_atime; /* last attach time */__kernel_time_t shm_dtime; /* last detach time */__kernel_time_t shm_ctime; /* last change time */__kernel_ipc_pid_t shm_cpid; /* pid of creator */__kernel_ipc_pid_t shm_lpid; /* pid of last operator */unsigned short shm_nattch; /* no. of current attaches */unsigned short shm_unused; /* compatibility */void *shm_unused2; /* ditto - used by DIPC */void *shm_unused3; /* unused */
};struct shmid_ds 是 System V 共享内存的状态信息结构体在 Linux 系统中用来描述共享内存段的属性和状态。下面是 struct shmid_ds 结构体中各个成员的含义
成员含义struct ipc_perm shm_perm用于描述共享内存的操作权限。int shm_segsz共享内存段的大小以字节为单位。__kernel_time_t shm_atime最后一次附加attach该共享内存的时间。__kernel_time_t shm_dtime最后一次分离detach该共享内存的时间。__kernel_time_t shm_ctime最后一次修改该共享内存的时间。__kernel_ipc_pid_t shm_cpid创建者进程的进程号PID。__kernel_ipc_pid_t shm_lpid最后一次操作该共享内存的进程号PID。unsigned short shm_nattch当前附加attach该共享内存的进程数。unsigned short shm_unused未使用的字段用于兼容性。void* shm_unused2未使用的字段由 DIPCDistributed Inter-Process Communication使用。void* shm_unused3未使用的字段。
通过这些状态信息我们可以获取共享内存段的大小、权限、最后访问时间、创建者信息以及当前附加进程的数量等相关信息。这些信息对于管理和监控共享内存非常有用能够帮助我们更好地理解和控制共享内存的状态。
三、共享内存的使用
1. 共享内存的使用步骤
1包含头文件
首先在程序中包含 sys/ipc.h、sys/shm.h 和 sys/types.h 头文件以便能够使用共享内存相关的函数和数据结构。
2获取键值ftok函数
ftok 函数是一个用于生成 System V IPC进程间通信键值的函数它通常用于创建消息队列、共享内存和信号量的标识符。其原型如下
key_t ftok(const char *pathname, int proj_id);pathname 参数是一个指向路径名的指针它引用一个现有的目录项。proj_id 是一个用户定义的整数用来区分不同的 IPC 对象。
ftok 函数会将给定的路径名和项目 ID 转换成一个唯一的 key 值以便在创建或获取 IPC 对象时使用。这个 key 值是一个标识 IPC 对象的关键参数确保了不同的 IPC 对象具有不同的标识符。
需要注意的是ftok 函数并不是一个完美的方法来生成唯一的 IPC 键值因为它对路径名和项目 ID 的要求比较严格而且在不同的系统上可能会有一些限制。另外由于 ftok 使用的是低位 8 位作为唯一标识所以在某些情况下可能存在冲突。可以类比C中的哈希函数
3创建共享内存段shmget函数
shmget 函数用于创建或获取一个共享内存段。它的原型如下
int shmget(key_t key, size_t size, int shmflg);key 是通过 ftok 函数生成的键值用于标识共享内存段。size 是共享内存段的大小以字节为单位。shmflg 是用来指定权限和行为的标志位。
shmget 函数的功能如下
如果以给定的键值 key 找到了一个共享内存段则返回该共享内存段的标识符非负整数。如果以给定的键值 key 没有找到对应的共享内存段则根据 shmflg 参数的设置来创建一个新的共享内存段并返回该共享内存段的标识符。当创建一个新的共享内存段时需要指定共享内存段的大小 size。如果创建成功操作系统会分配足够的内存空间来容纳这个大小的共享内存段并返回其标识符。shmflg 参数可以用来指定共享内存段的权限和行为例如读写权限、创建新的共享内存段还是获取已有的共享内存段等。
需要注意的是共享内存段在整个系统中是全局可见的可以被多个进程同时访问。因此在使用共享内存时需要确保进程之间的同步和互斥以避免数据竞争和不一致性的问题。
4将共享内存连接到当前进程的地址空间shmat函数
shmat 函数用于将共享内存段连接到当前进程的地址空间以便进程可以访问共享内存中的数据。它的原型如下
void *shmat(int shmid, const void *shmaddr, int shmflg);shmid 是共享内存段的标识符通常是由 shmget 函数返回的值。shmaddr 是用来指定将共享内存连接到进程地址空间的地址通常设为 NULL表示由系统自动选择合适的地址。shmflg 是用来指定连接行为的标志位。
shmat 函数的功能如下
将指定标识符的共享内存段连接到当前进程的地址空间并返回一个指向共享内存段起始地址的指针。如果 shmaddr 参数设为 NULL则系统会自动选择合适的地址将共享内存连接到当前进程的地址空间。shmflg 参数可以用来指定连接的行为例如是否只读、读写权限等。
✅在调用 shmat 函数后程序员可以通过返回的指针来访问共享内存中的数据。
5访问共享内存
连接成功后就可以通过返回的指针来访问共享内存中存储的数据了。
6分离共享内存shmdt函数
shmdt 函数用于将共享内存段从当前进程的地址空间分离以释放资源并防止内存泄漏。它的原型如下
int shmdt(const void *shmaddr);shmaddr 是指向共享内存段起始地址的指针需要与之前调用 shmat 函数时返回的指针相同。
shmdt 函数的功能如下
将共享内存段从当前进程的地址空间分离。分离后当前进程将无法再访问共享内存段中的数据。
下面是 shmdt 函数的示例用法
#include sys/types.h
#include sys/shm.h
#include stdio.hint main()
{void *ptr ...; // 已知指向共享内存的指针int status shmdt(ptr); // 将共享内存从当前进程的地址空间分离if (status -1) {perror(shmdt);return 1;}printf(Shared memory detached\n);return 0;
}需要注意的是分离共享内存后当前进程将无法再通过指针 ptr 访问共享内存中的数据。为避免内存泄漏使用完共享内存后应该及时调用 shmdt 函数分离共享内存。
2. 共享内存的使用示例
进程1创建共享内存并写入数据
#include sys/types.h
#include sys/ipc.h
#include sys/shm.h
#include stdio.h
#include string.hint main() {key_t key ftok(shmfile, R); // 通过 ftok 函数生成键值int size 1024; // 共享内存段的大小int shmflg IPC_CREAT | 0666; // 创建共享内存段的权限int shmid shmget(key, size, shmflg); // 获取共享内存的标识符if (shmid -1) {perror(shmget);return 1;}printf(Shared memory segment ID: %d\n, shmid);char *shmaddr shmat(shmid, NULL, 0); // 将共享内存连接到当前进程的地址空间if (shmaddr (char *)-1) {perror(shmat);return 1;}strcpy(shmaddr, Hello, shared memory!); // 向共享内存写入数据printf(Data written to shared memory: %s\n, shmaddr);shmdt(shmaddr); // 将共享内存从当前进程的地址空间分离return 0;
}进程2连接共享内存并读取数据
#include sys/types.h
#include sys/ipc.h
#include sys/shm.h
#include stdio.h
#include string.hint main() {key_t key ftok(shmfile, R); // 通过 ftok 函数生成键值int size 1024; // 共享内存段的大小int shmflg 0666; // 访问共享内存的权限int shmid shmget(key, size, shmflg); // 获取共享内存的标识符if (shmid -1) {perror(shmget);return 1;}char *shmaddr shmat(shmid, NULL, 0); // 将共享内存连接到当前进程的地址空间if (shmaddr (char *)-1) {perror(shmat);return 1;}printf(Data read from shared memory: %s\n, shmaddr); // 从共享内存读取数据shmdt(shmaddr); // 将共享内存从当前进程的地址空间分离// 在实际应用中可能需要在完成读取数据后删除共享内存段使用 shmctl 函数执行删除操作// shmctl(shmid, IPC_RMID, NULL);return 0;
}四、共享内存的优缺点
优点 快速高效 由于共享内存直接映射到进程的地址空间进程可以直接读写共享内存中的数据因此在性能上非常高效。 方便 共享内存提供了一个简单的机制允许多个进程共享相同的数据而无需进行复制或传输。这样可以方便地实现进程间的数据共享。 灵活性 共享内存可以用于任意类型的数据包括结构化数据、对象等因此非常灵活。
缺点 同步问题 由于多个进程可以同时访问共享内存因此需要额外的同步机制来确保数据的一致性和完整性比如信号量、互斥锁等。 安全性 共享内存的使用需要特别小心因为在没有适当的同步和保护机制的情况下可能会导致竞争条件和数据损坏。 复杂性 在设计和实现中共享内存可能会引入更多的复杂性需要开发人员自行管理内存分配、释放、同步等问题容易出现错误。 可移植性 共享内存的实现可能受限于操作系统因此在不同的平台上可能存在一定的可移植性问题。
温馨提示
感谢您对博主文章的关注与支持如果您喜欢这篇文章可以点赞、评论和分享给您的同学这将对我提供巨大的鼓励和支持。另外我计划在未来的更新中持续探讨与本文相关的内容。我会为您带来更多关于Linux以及C编程技术问题的深入解析、应用案例和趣味玩法等。如果感兴趣的话可以关注博主的更新不要错过任何精彩内容
再次感谢您的支持和关注。我们期待与您建立更紧密的互动共同探索Linux、C、算法和编程的奥秘。祝您生活愉快排便顺畅