网站备案最快,合肥网络推广有限公司,wordpress淘宝客主题使用说明,做网站对电脑要求高吗本文目录 一、共享内存1.1 shmget函数1.2 shmat1.3 shmdt1.4 shmctl1.5 ftok1.6 共享内存和内存映射的关联1.7 小demo 二、共享内存操作命令 一、共享内存
共享内存允许两个或者多个进程共享物理内存的同一块区域#xff08;通常被称为段#xff09;。由于一个共享内存段会称… 本文目录 一、共享内存1.1 shmget函数1.2 shmat1.3 shmdt1.4 shmctl1.5 ftok1.6 共享内存和内存映射的关联1.7 小demo 二、共享内存操作命令 一、共享内存
共享内存允许两个或者多个进程共享物理内存的同一块区域通常被称为段。由于一个共享内存段会称为一个进程用户空间的一部分因此这种 IPC 机制无需内核介入。所有需要做的就是让一个进程将数据复制进共享内存中并且这部分数据会对其他所有共享同一个段的进程可用。
共享内存是一种进程间通信IPC机制允许多个进程共享同一块物理内存区域。这种共享内存区域通常被称为共享内存段。共享内存段可以被映射到多个进程的用户空间中从而实现进程间的高效通信。虚拟内存映射每个进程的虚拟地址空间中会有一部分被映射到这块共享的物理内存上。当进程访问这块映射的虚拟内存区域时实际上是在访问共享的物理内存。由于这块内存被映射到进程的用户空间中进程可以直接访问它而不需要内核介入。 与管道等要求发送进程将数据从用户空间的缓冲区复制进内核内存和接收进程将数据从内核内存复制进用户空间的缓冲区的做法相比这种 IPC 技术的速度更快。内存映射相比共享内存效率会比较低。直接操作内存效率比较高。
创建或获取共享内存段
调用shmget()函数创建一个新的共享内存段或者获取一个已存在的共享内存段的标识符该共享内存段可能由其他进程创建。这个调用将返回一个共享内存标识符该标识符将在后续的调用中被使用。
将共享内存段附加到进程的虚拟内存
使用shmat()函数将共享内存段附加到调用进程的虚拟内存中使其成为进程虚拟内存的一部分。从这一刻起程序可以像对待其他普通内存一样使用这块共享内存。为了引用这块共享内存程序需要使用shmat()调用返回的addr值这是一个指向进程虚拟地址空间中共享内存段起点的指针。
分离共享内存段可选
调用shmdt()函数来分离共享内存段。分离后进程将无法再引用这块共享内存。这一步是可选的因为在进程终止时系统会自动完成这一步。
删除共享内存段
调用shmctl()函数来删除共享内存段。只有在所有附加到该共享内存段的进程都与之分离之后共享内存段才会被销毁。这一步通常只需要一个进程执行即可。
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);
key_t ftok(const char *pathname, int proj_id);1.1 shmget函数
#include sys/ipc.h
#include sys/shm.hint shmget(key_t key, size_t size, int shmflg);- 功能创建一个新的共享内存段或者获取一个既有的共享内存段的标识。新创建的内存段中的数据都会被初始化为0- 参数- key : key_t类型是一个整形通过这个找到或者创建一个共享内存。一般使用16进制表示非0值- size: 共享内存的大小- shmflg: 属性- 访问权限- 附加属性创建/判断共享内存是不是存在- 创建IPC_CREAT- 判断共享内存是否存在 IPC_EXCL , 需要和IPC_CREAT一起使用IPC_CREAT | IPC_EXCL | 0664- 返回值失败-1 并设置错误号成功0 返回共享内存的引用的ID后面操作共享内存都是通过这个值。#include stdio.h
#include stdlib.h
#include sys/ipc.h
#include sys/shm.h
#include unistd.hint main() {key_t key 0x1234; // 定义一个共享内存的键值通常使用16进制表示size_t size 1024; // 定义共享内存的大小以字节为单位int shmflg IPC_CREAT | 0664; // 设置共享内存的标志和访问权限// 调用 shmget 创建一个新的共享内存段或获取一个已存在的共享内存段的标识符int shmid shmget(key, size, shmflg);if (shmid -1) {perror(shmget failed); // 如果失败打印错误信息exit(EXIT_FAILURE);}printf(Shared memory created/obtained successfully. ID: %d\n, shmid);return 0;
}1.2 shmat
void *shmat(int shmid, const void *shmaddr, int shmflg);- 功能和当前的进程进行关联- 参数- shmid : 共享内存的标识ID,由shmget返回值获取- shmaddr: 申请的共享内存的起始地址指定NULL内核指定- shmflg : 对共享内存的操作- 读 SHM_RDONLY, 必须要有读权限- 读写 0- 返回值成功返回共享内存的首起始地址。 失败(void *) -1// 调用 shmat 将共享内存段附加到当前进程的虚拟内存中// 参数// - shmid: 共享内存的标识符// - shmaddr: 指定为NULL让内核选择合适的地址// - shmflg: 0 表示读写权限void *shmaddr shmat(shmid, NULL, 0);if (shmaddr (void *)-1) {perror(shmat failed);exit(EXIT_FAILURE);}printf(Shared memory attached at address: %p\n, shmaddr);1.3 shmdt
int shmdt(const void *shmaddr);- 功能解除当前进程和共享内存的关联- 参数shmaddr共享内存的首地址- 返回值成功 0 失败 -1if (shmdt(shmaddr) -1) {perror(shmdt failed);exit(EXIT_FAILURE);}printf(Shared memory detached successfully.\n);1.4 shmctl
int shmctl(int shmid, int cmd, struct shmid_ds *buf);- 功能对共享内存进行操作。删除共享内存共享内存要删除才会消失创建共享内存的进行被销毁了对共享内存是没有任何影响。- 参数- shmid: 共享内存的ID- cmd : 要做的操作- IPC_STAT : 获取共享内存的当前的状态- IPC_SET : 设置共享内存的状态- IPC_RMID: 标记共享内存被销毁- buf需要设置或者获取的共享内存的属性信息- IPC_STAT : buf存储数据- IPC_SET : buf中需要初始化数据设置到内核中- IPC_RMID : 没有用NULL// 删除共享内存段可选通常由最后一个使用它的进程完成if (shmctl(shmid, IPC_RMID, 0) -1) {perror(shmctl failed);exit(EXIT_FAILURE);}printf(Shared memory segment deleted.\n);
1.5 ftok
key_t ftok(const char *pathname, int proj_id);- 功能根据指定的路径名和int值生成一个共享内存的key- 参数- pathname:指定一个存在的路径/home/nowcoder/Linux/a.txt/ - proj_id: int类型的值但是这系统调用只会使用其中的1个字节范围 0-255 一般指定一个字符 a // 定义一个存在的路径名const char *pathname /home/nowcoder/Linux/a.txt;// 定义一个项目ID通常使用一个字符的ASCII值int proj_id a;// 调用 ftok 生成共享内存的键值key_t key ftok(pathname, proj_id);if (key -1) {perror(ftok failed);exit(EXIT_FAILURE);}printf(Generated key: %d\n, key);// 使用生成的键值创建或获取共享内存段size_t size 1024; // 定义共享内存的大小int shmflg IPC_CREAT | 0664; // 设置共享内存的标志和访问权限int shmid shmget(key, size, shmflg);if (shmid -1) {perror(shmget failed);exit(EXIT_FAILURE);}printf(Shared memory created/obtained successfully. ID: %d\n, shmid);问题1操作系统如何知道一块共享内存被多少个进程关联
操作系统通过维护一个结构体struct shmid_ds来跟踪共享内存段的状态。这个结构体中有一个成员shm_nattch它记录了当前与该共享内存段关联的进程个数。每当一个进程通过shmat函数附加到共享内存段时shm_nattch的值会增加而当一个进程通过shmdt函数分离共享内存段时shm_nattch的值会减少。通过这种方式操作系统能够实时了解每个共享内存段的使用情况。
问题2可不可以对共享内存进行多次删除shmctl
可以对共享内存进行多次调用shmctl进行删除操作。这是因为shmctl标记共享内存为删除状态并不是立即删除它。共享内存段的实际删除发生在与之关联的进程数为0时。当shm_nattch的值降为0表示没有进程再使用该共享内存段此时操作系统才会真正删除它。此外当共享内存的key值被设置为0时表示该共享内存段已被标记为删除。如果一个进程与共享内存取消关联那么该进程将无法继续操作该共享内存也不能再次进行关联。
1.6 共享内存和内存映射的关联
共享内存可以直接通过系统调用如shmget创建而内存映射通常需要一个磁盘文件作为后端支持匿名映射除外。共享内存的创建更为直接和简单而内存映射则需要额外的文件支持。
共享内存通常具有更高的效率。由于共享内存允许多个进程直接访问同一块物理内存因此在进程间通信时数据传输的开销较小。相比之下内存映射虽然也可以实现高效的内存访问但在某些情况下可能需要额外的文件操作这会增加一定的开销。
共享内存允许多个进程操作同一块物理内存这意味着所有进程看到的是同一个数据副本。而内存映射则为每个进程在自己的虚拟地址空间中提供了一个独立的内存映射。尽管这些映射可能指向同一块物理内存但每个进程的操作是独立的不会直接影响其他进程的内存映射。
即使一个进程突然退出共享内存仍然存在其他进程仍然可以继续访问和操作共享内存。但如果一个进程突然退出该进程的内存映射区会被销毁其他进程无法再访问该映射区。
如果运行共享内存的电脑死机或宕机共享内存中的数据会丢失因为共享内存依赖于系统的内存管理。如果电脑死机或宕机内存映射区的数据仍然存在因为这些数据是基于磁盘文件的。只要磁盘文件未被损坏数据仍然可以恢复。
当进程退出时该进程的内存映射区会被销毁。这意味着其他进程无法再访问该映射区。 当一个进程退出时它会自动与共享内存取消关联但共享内存本身仍然存在。共享内存只有在所有关联的进程都退出后才会被标记为删除。如果系统关机共享内存中的数据也会丢失。
1.7 小demo
#include stdio.h
#include sys/ipc.h
#include sys/shm.h
#include string.hint main() { // 1.获取一个共享内存int shmid shmget(100, 0, IPC_CREAT);printf(shmid : %d\n, shmid);// 2.和当前进程进行关联void * ptr shmat(shmid, NULL, 0);// 3.读数据printf(%s\n, (char *)ptr);printf(按任意键继续\n);getchar();// 4.解除关联shmdt(ptr);// 5.删除共享内存shmctl(shmid, IPC_RMID, NULL);return 0;
}#include stdio.h
#include sys/ipc.h
#include sys/shm.h
#include string.hint main() { // 1.创建一个共享内存int shmid shmget(100, 4096, IPC_CREAT|0664);printf(shmid : %d\n, shmid);// 2.和当前进程进行关联void * ptr shmat(shmid, NULL, 0);char * str helloworld;// 3.写数据memcpy(ptr, str, strlen(str) 1);//设置一个等待操作不然会进程直接结束那么共享内存也没了。printf(按任意键继续\n);getchar();// 4.解除关联shmdt(ptr);// 5.删除共享内存shmctl(shmid, IPC_RMID, NULL);return 0;
}二、共享内存操作命令
ipcs -a // 打印当前系统中所有的进程间通信方式的信息
ipcs -m // 打印出使用共享内存进行进程间通信的信息
ipcs -q // 打印出使用消息队列进行进程间通信的信息
ipcs -s // 打印出使用信号进行进程间通信的信息图中的共享内存段的键是0x0000已经被标记删除了但是因为连接数还存在所以没有被删除。
ipcrm -M shmkey // 移除用shmkey创建的共享内存段
ipcrm -m shmid // 移除用shmid标识的共享内存段
ipcrm -Q msgkey // 移除用msqkey创建的消息队列
ipcrm -q msqid // 移除用msqid标识的消息队列
ipcrm -S semkey // 移除用semkey创建的信号
ipcrm -s semid // 移除用semid标识的信号
文章转载自: http://www.morning.ndxss.cn.gov.cn.ndxss.cn http://www.morning.dxpzt.cn.gov.cn.dxpzt.cn http://www.morning.rjjjk.cn.gov.cn.rjjjk.cn http://www.morning.zcqgf.cn.gov.cn.zcqgf.cn http://www.morning.swlwf.cn.gov.cn.swlwf.cn http://www.morning.qnxtz.cn.gov.cn.qnxtz.cn http://www.morning.pflry.cn.gov.cn.pflry.cn http://www.morning.dgfpp.cn.gov.cn.dgfpp.cn http://www.morning.mnsmb.cn.gov.cn.mnsmb.cn http://www.morning.bytgy.com.gov.cn.bytgy.com http://www.morning.mnkz.cn.gov.cn.mnkz.cn http://www.morning.xuejitest.com.gov.cn.xuejitest.com http://www.morning.gwjqq.cn.gov.cn.gwjqq.cn http://www.morning.zylrk.cn.gov.cn.zylrk.cn http://www.morning.qzpsk.cn.gov.cn.qzpsk.cn http://www.morning.yqpck.cn.gov.cn.yqpck.cn http://www.morning.roymf.cn.gov.cn.roymf.cn http://www.morning.drzkk.cn.gov.cn.drzkk.cn http://www.morning.kfyqd.cn.gov.cn.kfyqd.cn http://www.morning.pybqq.cn.gov.cn.pybqq.cn http://www.morning.lwxsy.cn.gov.cn.lwxsy.cn http://www.morning.pqcbx.cn.gov.cn.pqcbx.cn http://www.morning.rjznm.cn.gov.cn.rjznm.cn http://www.morning.jnptt.cn.gov.cn.jnptt.cn http://www.morning.pgkpt.cn.gov.cn.pgkpt.cn http://www.morning.rmpfh.cn.gov.cn.rmpfh.cn http://www.morning.stprd.cn.gov.cn.stprd.cn http://www.morning.ygmw.cn.gov.cn.ygmw.cn http://www.morning.nfgbf.cn.gov.cn.nfgbf.cn http://www.morning.nqcts.cn.gov.cn.nqcts.cn http://www.morning.tkryt.cn.gov.cn.tkryt.cn http://www.morning.ghccq.cn.gov.cn.ghccq.cn http://www.morning.sqmlw.cn.gov.cn.sqmlw.cn http://www.morning.hbjqn.cn.gov.cn.hbjqn.cn http://www.morning.jrtjc.cn.gov.cn.jrtjc.cn http://www.morning.qsdnt.cn.gov.cn.qsdnt.cn http://www.morning.lgphx.cn.gov.cn.lgphx.cn http://www.morning.sfphz.cn.gov.cn.sfphz.cn http://www.morning.nqrfd.cn.gov.cn.nqrfd.cn http://www.morning.lkmks.cn.gov.cn.lkmks.cn http://www.morning.lrflh.cn.gov.cn.lrflh.cn http://www.morning.fbylq.cn.gov.cn.fbylq.cn http://www.morning.zgpgl.cn.gov.cn.zgpgl.cn http://www.morning.msbct.cn.gov.cn.msbct.cn http://www.morning.yrnyz.cn.gov.cn.yrnyz.cn http://www.morning.ngqdp.cn.gov.cn.ngqdp.cn http://www.morning.mnpdy.cn.gov.cn.mnpdy.cn http://www.morning.qgfkn.cn.gov.cn.qgfkn.cn http://www.morning.hcwjls.com.gov.cn.hcwjls.com http://www.morning.ltffk.cn.gov.cn.ltffk.cn http://www.morning.yrbhf.cn.gov.cn.yrbhf.cn http://www.morning.djxnw.cn.gov.cn.djxnw.cn http://www.morning.rqnml.cn.gov.cn.rqnml.cn http://www.morning.ydflc.cn.gov.cn.ydflc.cn http://www.morning.lzqdd.cn.gov.cn.lzqdd.cn http://www.morning.kxqwg.cn.gov.cn.kxqwg.cn http://www.morning.tkrwm.cn.gov.cn.tkrwm.cn http://www.morning.kbynw.cn.gov.cn.kbynw.cn http://www.morning.ksjmt.cn.gov.cn.ksjmt.cn http://www.morning.hytfz.cn.gov.cn.hytfz.cn http://www.morning.nnpfz.cn.gov.cn.nnpfz.cn http://www.morning.ychoise.com.gov.cn.ychoise.com http://www.morning.cnkrd.cn.gov.cn.cnkrd.cn http://www.morning.pcxgj.cn.gov.cn.pcxgj.cn http://www.morning.ltxgk.cn.gov.cn.ltxgk.cn http://www.morning.qwnqt.cn.gov.cn.qwnqt.cn http://www.morning.lmyq.cn.gov.cn.lmyq.cn http://www.morning.ljbch.cn.gov.cn.ljbch.cn http://www.morning.flxqm.cn.gov.cn.flxqm.cn http://www.morning.gjsjt.cn.gov.cn.gjsjt.cn http://www.morning.nafdmx.cn.gov.cn.nafdmx.cn http://www.morning.jbtlf.cn.gov.cn.jbtlf.cn http://www.morning.swzpx.cn.gov.cn.swzpx.cn http://www.morning.beiyishengxin.cn.gov.cn.beiyishengxin.cn http://www.morning.lwrcg.cn.gov.cn.lwrcg.cn http://www.morning.lyhry.cn.gov.cn.lyhry.cn http://www.morning.tzzxs.cn.gov.cn.tzzxs.cn http://www.morning.lxhrq.cn.gov.cn.lxhrq.cn http://www.morning.chongzhanggui.cn.gov.cn.chongzhanggui.cn http://www.morning.lddpj.cn.gov.cn.lddpj.cn