- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
虚拟内存、内核空间和用户空间 内核空间(1GB) 进程1的用户空间(3GB) 进程2的用户空间(3GB) ? 进程n的用户空间(3GB) 虚拟地址空 间 32位寻址最大可支持4G的内存(在32位的x86机器, 2^32 =4G),而实际上linux用户面对的不是物理内存,是4G的虚拟内存。 虚拟内存分两部分: 内核空间(3G-4G,虚地址0xC0000000到0xFFFFFFFF ) 编译链接时内核相关程序和数据被编址到这个部分 用户空间(较低的3G字节,虚地址00xBFFFFFFF ) 编译链接时进程的相关代码和数据被编址到这个部分 从具体进程的角度看,每个进程都拥有各自独立的4GB虚拟地址空间(虚拟内存)。 进程最大拥有3G字节私有虚存空间,这些私有空间映射在内存哪里由各进程的页表决定。 Linux内核空间对系统内的所有进程是共享的 ——每个进程都可以通过系统调用进入内核,所以是共享的;虽然内核空间占据了每个虚拟空间中的最高1GB字节,但映射到物理内存却总是从最低地址(0开始的,它的映射机制和用户的不一样 程序编译连接后形成的虚拟地址空间,装入时形成mm_struct意谓着进程的虚拟地址空间描述完成。 * 进程的空间 始终从进程虚拟地址空间的角度看 * malloc、vmalloc等申请内存的操作函数实际上也都是从4G的虚拟内存中申请空间。 进程通信中提到的共享内存通过将同一块物理内存(常为一种文件)映射到进程A、B各自的内存,两个进程可快速感知对方的修改,这里的映射就是在进程虚拟内存的用户空间上映射的。 也就是说内存分配是①申请虚拟内存②再映射到物理内存,至于这些申请的空间具体映射到内存哪里由系统具体分配和构建的页表决定。 * 区分用户空间和内核空间 为什么共享内存是最快的IPC: 消息队列和信号量、管道等对象,经由它们的数据需要在内核和用户空间进行额外的数据拷贝;而共享内存和访问它的所有进程都处于用户空间,进程通过地址映射的方式直接读写内存,从而获得非常高的通信效率。当然,由于被映射的物理内存被多个进程共享,共享内存往往需要搭配某种同步机制如信号量。 * linux支持多种共享内存方式(选看) ① POSIX共享内存对象 :shm_open创建一个名称为tmp的共享内存区对象后,在/dev/shm/下可以看到对应的文件(tmpfs的文件系统?可以看成是直接对内存操作,速度非常快 ) cat可以看到内容。 进程重启共享内存中数据不会丢失,内核自举或显示调用shm_unlink或rm掉文件删除后丢失 ② POSIX文件映射:通过映射一个普通文件(匿名文件或一个打开的命名文件)实现共享内存——mmap()。 该方式接口简单,较通用。可利用cat查看映射的文件,要注意考虑进程终止对通信的影响。 ③ systemV共享内存:通过映射特殊存储块shm中的文件实现进程间的共享内存通信——主要有以下几个API:shmget()、shmat()、shmdt()及shmctl()。 本方式无法看到文件实体。 进程重启共享内存中数据不会丢失,内核自举或显示调用shmdt或使用ipcrm删除后丢失。 * 举例:在进程用户空间映射一个共享匿名虚存区实现共享内存 父子进程共享一个4字节的匿名区,利用内存区传递信息 #include sys/mman.h #include stdio.h #include unistd.h #define N 10 int main(){ int i,sum,fd; int *result= mmap (0,4,PORT_READ|PORT_WRITE,MAP_SHARED|MAP_ANONYMOUS,0,0) int pid=fork(); if (pid==0){ //子进程 for(sum=0,i=1;iN;i++) sum+=i; *result=sum; printf(“child %d write: result =%d,sum=%d\n”,getpid(),*result,sum); }else{ //父进程 wait(0); printf(“farther %d : result =%d,sum=%d\n”,getpid(),*result,sum); } printf(“we’re going to sleep 20 seconds,see us in /proc \n”); sleep(20); if (pid0) munmap(result,4); sleep(20); } 执行结果:farther: result=45,sum=134518632 父子进程result指
文档评论(0)