本文主要是介绍初步认识共享内存(并不全面),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
共享内存是系统处于多个进程之间通讯的考虑,而预留的一块内存区。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据的传递就不再涉及内核(即进程不再通过执行任何进入内核的系统调用来彼此传递数据).共享内存是最高效的IPC机制,因为它不涉及进程之间的任何数据传输。两个不同进程A和B共享内存的意思是,同一块物理内存被映射到进程A、B各自的进程地址空间。进程A可以即时看到B对共享内存中的数据的更新。
当然,既然是共享,必然需要某种共享机制,互斥锁、信号量等
共享内存方式,进程可以直接读取内存,而不需要数据的拷贝,因此速度挺快。
举个例子,【客户服务器文件复制程序】(即同一系统中一个进程读source文件数据发送给另一个进程写道destination文件中)中的通常步骤:
1、服务器从输入文件读,该文件的数据由内核读入自己的内存空间,然后从内核复制到服务器进程
2、服务器往一个管道、FIFO或消息队列以一条消息的形式写入这些数据。这些IPC形式通常需要把这些数据从进程复制到内核。
3、客户从该IPC通道读出这些数据,这通常需要把这些数据从内核复制到进程
4、最后,将这些数据从由write函数的第二个参数指定的客户缓冲区复制到输出文件
这里总共需要四次数据复制,而且这四次是在内核和进程间进行的,往往开销很大
然而,通过让两个或两个以上进程共享一个内存区,就绕过了上述的问题。当然,这些进程必须协调或同步对该共享去内存的使用。
因此,现在步骤如下:
1、服务器使用(譬如)一个信号量取得访问某个共享内存区对象的权力。
2、服务器将数据从输入文件读入到共享内存区对象。read函数的第二个参数指向这个共享内存区对象
3、服务器读入完毕时,使用一个信号量通知客户
4、客户将这些数据从该共享内存区对象写出到输出文件中
从这里看出,总共复制了两次,即从文件到共享内存区和从共享内存区到文件
要强调的是,默认情况下通过fork派生的子进程并不与其父进程共享内存区
void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset);
//mmap函数把一个文件或者一个POSIX共享内存区对象映射到调用进程的地址空间
//使用此函数有3个目的:
//1、使用普通文件以提供内存映射I/O
//2、使用特殊文件以提供匿名内存映射
//3、使用sem_open以提供无亲缘关系进程间的POSIX共享内存区
//其中addr可以指定描述符被映射到的进程内存空间的起始地址,常为空指针,告诉内核自己去选择地址
//
这篇关于初步认识共享内存(并不全面)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!