自制补水美白面膜:共享内存的几点总结

来源:百度文库 编辑:九乡新闻网 时间:2024/05/02 22:43:22

在实验过程中,有些同学总对共享内存的一些概念弄不清,特别总结了下:

所谓共享内存就是多个进程间共同使用同一段物理内存空间,它是通过将同一段物理内存映射到不同进程的虚空间中来实现的。由于映射到不同进程的虚空间中,不同进程可以直接使用,不需要进行内存的复制,所以共享内存的效率很高。

共享内存分2种:

1.二者是用同一种机制完成的,不同的是用户接口不同:
        一种是POSIX的共享内存,通过用户空间挂载的tmpfs文件系统实现的。(上层不会在意你是内核还是用户空间来实现的)
        二种是system V的共享内存是由内核本身的tmpfs实现的。(严格由操作系统内核提供接口和实现。)

2.posix的共享内存机制实际上在库过程中以及用户空间的其他部分被展示为完全的文件系统的调用过程,在调用完shm_open之后,需要调用mmap来将tmpfs的文件映射到地址空间,接着就可以操作这个文件了,需要注意的是,别的进程也可以操作这个文件,因此这个文件其实就是共享内存。

反观systemv的共享内存,内核直接实现了shmget/at系统调用,虽然最终也是靠tmpfs来实现的,但是接口设计上和posix完全不同,posix旨在提供所有系统都一致的接口,而systemv只在于实现自己的逻辑,共享内存其实只是sysv中ipc的一部分,最终的管理数据结构也是ipc的而不是共享内存的

3.不管是systemv的还是POSIX的共享内存,在计算机重新启动之后都不复存在,因为数据是都保存在物理存储器上或交换分区中。他们不同的是,POSIX是以用户空间文件实现的,并且用户空间操作的是文件描述符,文件描述符是属于task_struct的,因此进程退出之后共享内存将递减共享计数,如果为0的时候则销毁,因此POSIX的共享内存虽然使用OPEN来创建或打开共享内存并没有用close而是用unlink来关闭的,作用就是在计数为0的时候销毁它,看看systemv的共享内存,虽然也是由文件实现的,但是文件并没有加入到进程的打开文件表,而是作为进程的一种内禀属性被使用的,因此在进程退出时并不关闭文件,只要机器不重启或者该共享内存不显式销毁,那么共享内存将一直存在,进程和文件其实是互不相关的两个概念,只是进程打开的文件才和进程相关,在进程结束的时候只是能保证与之相关的文件被关闭,而别的文件比如sysv的共享内存使用的文件结构没有和进程关联,因此不会被关闭。其实close并不操作什么,而是仅仅刷新缓冲区,然后递减文件的使用者计数。

例:
        int filp_close(struct file *filp, fl_owner_t id)
        {
                int retval = 0;
                if (!file_count(filp)) {
                printk(KERN_ERR "VFS: Close: file count is 0\n");
                return 0;
        }

4.如何达到共享内存的目的

在Linux系统中,每个进程的虚拟内存是被分为许多页面的。这些内存页面中包含了实际的数据。每个进程都会维护一个从内存地址到虚拟内存页面之间的映射关系。尽管每个进程都有自己的内存地址,不同的进程可以同时将同一个内存页面映射到自己的地址空间中,从而达到共享内存的目的。

5.共享内存的优缺点

共享内存块提供了在任意数量的进程之间进行高效双向通信的机制。每个使用者都可以读取写入数据,但是所有程序之间必须达成并遵守一定的协议,以防止诸如在读取信息之前覆写内存空间等竞争状态的出现。不幸的是,Linux无法严格保证提供对共享内存块的独占访问,甚至是在您通过使用IPC_PRIVATE创建新的共享内存块的时候也不能保证访问的独占性。 同时,多个使用共享内存块的进程之间必须协调使用同一个键值。