Linux进程通信IPC--共享内存SharedMemory

来源:互联网 发布:套利定价知乎 编辑:程序博客网 时间:2024/05/18 02:59

前言: Linux 进程通信系列文章是对工作中使用的技术进行描述总结,使用了Boost 库IPC 实现,因此文章的代码部分选自Boost example 文档。

共享内存(SharedMemory)

共享内存是进程间最快的通信机制,不同进程将同一块内存区域映射到各自的进程地址空间,获取地址后即可对该地址空间的内存区域进行读写操作。由于进程运行的独立性,对公共内存区域的读写不可避免产生竞争,因此也就需要同步机制保护公共区域。

与消息队列(MessageQueue)相比,共享内存机制避免了一次内核空间到用户空间的copy 操作, 而采用直接映射公共区域到进程地址空间的方式。

共享内存实现

Boost Interprocess 编程提供了跨平台的共享内存实现, 通过shared_memory_object 类。

  • 创建共享内存区域
shared_memory_object(                     create_only_t,      //open_or_create_t, open_only_t                     const char *name,   //名称,唯一标识一块共享内存                     mode_t mode,        //访问模式,读/写/读写                     const permissions &perm = permissions())

shared_memory_object类型的对象创建后,相应的共享内存就在操作系统中建立了。但此共享内存区域的大小被初始化为0, 需要调用 truncate() 函数请求大小后才能使用该区域。

  • 指定内存区域大小
void truncate(offset_t length);  //以字节为单位指定共享内存区域大小

提醒注意的是,该函数只能在共享内存以read_write 方式打开时调用,否则将抛出异常。

  • 映射共享内存至进程空间

当共享内存被进程创建/打开后,进程必须映射共享内存对象至地址空间, 使用者可以映射整个或者部分共享内存,boost IPC的mapped_region类完成映射过程,完成映射后, 进程即可通过地址访问该共享内存区域。

template<class MemoryMappable>mapped_region(const MemoryMappable& mapping,                 mode_t mode,   // Access mode                 offset_t offset = 0, //Offset from the beginning of shm                 std::size_t size = 0, //Length of the region                 const void *address = 0,                 map_options_t map_options = default_map_options);std::size_t get_size() const;    //the size of the mappingvoid*       get_address() const;   //the base address of the mapping

删除共享内存区域

static bool remove(const char *name);  //erases a shared memory object from the system.

共享内存使用举例

使用example,选自boost 官方文档:

int main(int argc, char *argv[]){    using namespace boost::interprocess;    if(argc == 1){  //Parent process        //Remove shared memory on construction and destruction        struct shm_remove        {            shm_remove() { shared_memory_object::remove("MySharedMemory"); }            ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }        } remover;        //Create a shared memory object.        shared_memory_object shm (create_only, "MySharedMemory", read_write);        //Set size        shm.truncate(1000);        //Map the whole shared memory in this process        mapped_region region(shm, read_write);        //Write all the memory to 1        std::memset(region.get_address(), 1, region.get_size());        //Launch child process        std::string s(argv[0]); s += " child ";        if(0 != std::system(s.c_str()))            return 1;    }    else{        //Open already created shared memory object.        shared_memory_object shm (open_only, "MySharedMemory", read_only);        //Map the whole shared memory in this process        mapped_region region(shm, read_only);        //Check that memory was initialized to 1        char *mem = static_cast<char*>(region.get_address());        for(std::size_t i = 0; i < region.get_size(); ++i)            if(*mem++ != 1)                 return 1;   //Error checking memory    }    return 0;}

需要注意:由于该例子简单易懂, 进程间不存在竞争访问资源情况,文章未介绍进程读写共享内存的同步机制,之后的系列文章中将介绍进程间同步机制。

0 0
原创粉丝点击