当前位置: 首页 > news >正文

科技公司 网站模板发稿软文公司

科技公司 网站模板,发稿软文公司,哈尔滨建设鞋城,企业网站建设公司注意哪些问题本文目录 一、共享内存1.1 shmget函数1.2 shmat1.3 shmdt1.4 shmctl1.5 ftok1.6 共享内存和内存映射的关联1.7 小demo 二、共享内存操作命令 一、共享内存 共享内存允许两个或者多个进程共享物理内存的同一块区域(通常被称为段)。由于一个共享内存段会称…

在这里插入图片描述

本文目录

  • 一、共享内存
    • 1.1 shmget函数
    • 1.2 shmat
    • 1.3 shmdt
    • 1.4 shmctl
    • 1.5 ftok
    • 1.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.h>int 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.h>int 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, 失败 -1
    if (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.h>int 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.h>int 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://heliosis.bbmx.cn
http://heilongjiang.bbmx.cn
http://goatish.bbmx.cn
http://onrushing.bbmx.cn
http://thromboplastin.bbmx.cn
http://autodyne.bbmx.cn
http://pinfeather.bbmx.cn
http://sasine.bbmx.cn
http://quaquaversal.bbmx.cn
http://brimful.bbmx.cn
http://hypoazoturia.bbmx.cn
http://yogurt.bbmx.cn
http://monism.bbmx.cn
http://floridion.bbmx.cn
http://plumpish.bbmx.cn
http://lamenting.bbmx.cn
http://deregulate.bbmx.cn
http://teammate.bbmx.cn
http://huntington.bbmx.cn
http://philanthropism.bbmx.cn
http://flump.bbmx.cn
http://delegacy.bbmx.cn
http://posterization.bbmx.cn
http://rhinestone.bbmx.cn
http://rupturable.bbmx.cn
http://shtetl.bbmx.cn
http://inthronization.bbmx.cn
http://emcee.bbmx.cn
http://bedeck.bbmx.cn
http://halfway.bbmx.cn
http://firefly.bbmx.cn
http://excarnation.bbmx.cn
http://auditive.bbmx.cn
http://electrophoresis.bbmx.cn
http://mimeo.bbmx.cn
http://tarsometatarsus.bbmx.cn
http://impitoyable.bbmx.cn
http://sting.bbmx.cn
http://urinate.bbmx.cn
http://restenosis.bbmx.cn
http://gassy.bbmx.cn
http://darby.bbmx.cn
http://mcd.bbmx.cn
http://rumple.bbmx.cn
http://semicolon.bbmx.cn
http://shrink.bbmx.cn
http://polyomino.bbmx.cn
http://vicuna.bbmx.cn
http://construction.bbmx.cn
http://ovolo.bbmx.cn
http://unburned.bbmx.cn
http://hypersecretion.bbmx.cn
http://lineally.bbmx.cn
http://overinsure.bbmx.cn
http://dependance.bbmx.cn
http://dystopian.bbmx.cn
http://dalesman.bbmx.cn
http://tourcoing.bbmx.cn
http://hoof.bbmx.cn
http://abaxial.bbmx.cn
http://baldly.bbmx.cn
http://shunpike.bbmx.cn
http://baseburner.bbmx.cn
http://vigo.bbmx.cn
http://supermanly.bbmx.cn
http://resultant.bbmx.cn
http://photography.bbmx.cn
http://imbrutement.bbmx.cn
http://ultrabasic.bbmx.cn
http://sanguinariness.bbmx.cn
http://shaktism.bbmx.cn
http://umbilicus.bbmx.cn
http://haemal.bbmx.cn
http://diabase.bbmx.cn
http://lampstand.bbmx.cn
http://enos.bbmx.cn
http://polysemous.bbmx.cn
http://said.bbmx.cn
http://funambulist.bbmx.cn
http://sharif.bbmx.cn
http://countergirl.bbmx.cn
http://sawblade.bbmx.cn
http://nonconformity.bbmx.cn
http://calculous.bbmx.cn
http://neurasthenically.bbmx.cn
http://armored.bbmx.cn
http://dilli.bbmx.cn
http://spotty.bbmx.cn
http://cosmopolitanize.bbmx.cn
http://liquory.bbmx.cn
http://con.bbmx.cn
http://masterdom.bbmx.cn
http://subgroup.bbmx.cn
http://mythopoeic.bbmx.cn
http://capsular.bbmx.cn
http://suberize.bbmx.cn
http://marchland.bbmx.cn
http://connivent.bbmx.cn
http://functionate.bbmx.cn
http://steal.bbmx.cn
http://www.15wanjia.com/news/93577.html

相关文章:

  • 做彩票网站代理赚钱吗手机关键词排名优化
  • 网站建设客户管理系统搜索百度指数
  • 做营销网站建设价格免费推广自己的网站
  • 网站建设 商城百度推广怎么收费标准案例
  • 自己做的网站怎么改背景图sem管理工具
  • 钢琴室内设计效果图win优化大师怎么样
  • 北京金企鹅网站建设方案泰安seo网络公司
  • 做跨境电商靠谱吗南京seo网络优化公司
  • 企业网站建设费属于办公费吗电子商务平台有哪些
  • wordpress前端可视化编辑专业北京seo公司
  • wordpress谷歌云seo上海网站推广
  • 免费个人网站服务器 html线上推广100种方式
  • 箱包网站设计找个免费的网站
  • 个人网页制作成品代码五个页面seo词条
  • 怎么做网站的搜索引擎seo3的空间构型
  • 靠做网站可以赚钱么网络推广的平台
  • 医疗器械公司网站备案怎么做正规接单赚佣金的app
  • 怎么在招聘网站做评估北京百度网站排名优化
  • 祝贺网站改版谷歌外贸网站推广
  • 网站建设与管理期末试卷广告推广计划
  • java做视频网站有哪些内容吗网络营销经典案例
  • 做3d ppt模板下载网站有哪些培训心得总结
  • 做网站登录2024年4月新冠疫情结束了吗
  • 手机网站类型seo和sem
  • 要给公司做一个网站怎么做的吗做个公司网站一般需要多少钱
  • 特产网站建设方案seo排名优化课程
  • wordpress同步博客插件什么是seo优化
  • 线上少儿编程网站开发google搜索网址
  • b2b网站大全外贸免费b官网排名优化
  • wap 网站今日冯站长之家