服务器打开共享内存的初始化

服务器共享内存以及客户端打开服务器获得通知过程
打开GS就会进行共享内存的初始化,过程很复杂,看了很多次,今天看的时候终于了解了大概了
bool DataLayer::init()
{
    int pid = GetCurrentProcessId();
    auto path = Plug::GetCurrentPath();
    path += L"pid.txt";
    auto file = _wfopen(path.c_str(), L"wb");
    char buf[10] = {0};
    itoa(pid, buf, 10);
    fwrite(buf, 6, 1, file);//把当前GS进程的进程号写入到pid.txt,NET进程可以通过名字获得共享内存的名字
    fclose(file);

    m_spShareMemInter = NEWSP(shareMemInter);

    m_spShareMemInter->init("网络", pid);

    //创建网络子进程
    if(!CreateNetProcess())
    {
        Plug::PlugMessageBox(L"启动Net进程失败!");
        return false;
    }
    return true;
}
//共享内存的初始化
void shareMemInter::init(const char* name, int pid)
{
    std::string name2 = name;

    m_a2b.init(name2, pid);

    name2 += "-回发";
    m_b2a.init(name2, pid, 2);
}

//单边共享内存的初始化
void shareMemInterOneway::init(std::string name, int pid, int more)
{
    //初始化三种共享内存
    m_ProcessMemPool.init(name, pid, more);

    m_pid = pid;
    //针对mutex的共享内存,主要是为了互斥的访问m_ShareMemQue
    m_shm = new shared_memory_object(open_or_create, getMemName(name + "mux", m_pid).c_str(), read_write);
    m_shm->truncate(sizeof(mem镜像));

    mapped_region* m_region = new mapped_region(*m_shm, read_write);

    void* addr = m_region->get_address();

    m_mem镜像 = new (addr) mem镜像;
    //此处又创建队列共享内存,这个是用的时候从内存池取一块内存然后放入到这个队列里面来,在这个地方卡了很久
    m_segment = new managed_shared_memory(open_or_create, getMemName(name + "MySharedMemory9", m_pid).c_str(), 1024 * 1024 * 10 * more);

    m_ShareMemQue = m_segment->find_or_construct<mem_queue>(getMemName(name + "MySharedMemory92", m_pid).c_str())(mem_allocator(m_segment->get_segment_manager())); 

}
//这个过程看了很久,很久,也是刚看懂的
void ProcessMemPool::init(int memSize, int buffer_num, std::string name, int pid)
{
    m_memSize = memSize;
    m_buffer_num = buffer_num;
    m_name = name;
    m_pid = pid;
    //共享内存存储bool是否初始化
    auto shm = new shared_memory_object(open_or_create, getMemName(m_name + "mux2", pid).c_str(), read_write);
    shm->truncate(sizeof(bool));
    mapped_region* m_region = new mapped_region(*shm, read_write);
    void* addr = m_region->get_address();

    m_镜像 = (ProcessMemPoolmem镜像*)(addr);
    //大小1024*buffer_num托管共享内存,存储的是boost里面的queue
    /*
    一般stl里面的容器是不能放到共享内存里面的,因为他的内存不是在共享内存上分配的,主要跟他的分配器有关系
    此时就需要使用boost自己定义的对应的容器
    这个m_queue就是共享内存索引的作用,通过其中的index获取共享内存的地址
    */
    m_segment = new managed_shared_memory(open_or_create, getMemName(m_name + "ProcessMemPool9", pid).c_str(), 1024*buffer_num/*1024*1024*10*2*/);
    m_queue = m_segment->find_or_construct<mem_queue>(getMemName(m_name + "m_queue", pid).c_str())(mem_allocator(m_segment->get_segment_manager()));      

//    ---------------------------------
    //共享内存
    auto shm2 = new shared_memory_object(open_or_create, getMemName(name + "memall2", pid).c_str(), read_write);
    shm2->truncate(m_memSize * (m_buffer_num + 10));
    mapped_region* m_region2 = new mapped_region(*shm2, read_write);
    m_start_addr = m_region2->get_address();

    if(m_镜像->is_inited)//判断共享内存是否已被初始化
    {
        return ;
    }
    m_镜像->is_inited = true;
    //初始化共享queue,就是向其中插入shareDataEx
    for (int i = 0; i < m_buffer_num; i++)
    {
        shareDataEx sd;
        sd.index = i;
        sd.size = 0;
        sd.total_size = m_memSize;
        m_queue->push_back(sd);
    }
}
由于这里的共享内存都是open_or_create所以NET进程初始化共享内存的时候当其看到同名的共享内存的时候就会打开,没有的话就会创建
时间: 2024-08-03 15:17:01

服务器打开共享内存的初始化的相关文章

共享内存初始化

现在就来看看共享内存的初始化(过程是非常复杂的,也看了好多次) 1.内存池(其实这个也是放到共享内存里面) { 其中包括小,中,大三种模式,就以小举个例子 1.是否初始化m_镜像,表示2是否初始化, 2.托管内存队列:就是把shareDataEx类型的对象填充到托管的内存队列中 3.内存池:针对内存池分配的内存,这个应该和托管的队列是有联系的 } 进程锁:boost进程锁 共享内存:真正交互的是这个内存,到时细看下,这个和内存池是怎么交互的 m_a2b--->GS->NET(名字叫"

进程间通信(9) - 共享内存(System V)

1.前言 本篇文章的所有例子,基于RHEL6.5平台(linux kernal: 2.6.32-431.el6.i686). 2.介绍 共享内存也是一种IPC,它是目前最快的IPC,它的使用方式是将同一个内存区映射到共享它的不同进程的地址空间中,这样这些进程间的通信就不再需要通过内核,只需对该共享的内存区域进程操作就可以了. 共享内存与其他的进程间通信最大的优点是:数据的复制只有两次,一次是从输入文件到共享内存区,一次从共享内存区到输出文件.而其他的则是需要复制4次:服务器将输入文件读入自己的进

linux使用共享内存通信的进程同步退出问题

两个甚至多个进程使用共享内存(shm)通信,总遇到同步问题.这里的“同步问题”不是说进程读写同步问题,这个用信号量就好了.这里的同步问题说的是同步退出问题,到底谁先退出,怎么知道对方退出了.举个例子:进程负责读写数据库A,进程B负责处理数据.那么进程A得比进程B晚退出才行,因为要保存进程B处理完的数据.可是A不知道B什么时候退出啊.A.B是无关联的进程,也不知道对方的pid.它们唯一的关联就是读写同一块共享内存.正常情况下,进程B在共享内存中写个标识:进程A你可以退出了,也是可以的.不过进程B可

Boost:shared_memory_object --- 共享内存

什么是共享内存 共享内存是最快速的进程间通信机制.操作系统在几个进程的地址空间上映射一段内存,然后这几个进程可以在不需要调用操作系统函数的情况下在那段内存上进行读/写操作.但是,在进程读写共享内存时,我们需要一些同步机制. 考虑一下服务端进程使用网络机制在同一台机器上发送一个HTML文件至客户端将会发生什么: 服务端必须读取这个文件至内存,然后将其传至网络函数,这些网络函数拷贝那段内存至操作系统的内部内存. 客户端使用那些网络函数从操作系统的内部内存拷贝数据至它自己的内存. 如上所示,这里存在两

一个基于共享内存的ipc通信框架

一个基于共享内存的ipc通信框架 与共享内存相关的操作主要包括共享内存的初始化, 共享内存的释放, 共享内存的锁的相关操作, 在这里操作共享内存的环境是: 1 多个进程没有亲缘关系, 也没有server/client关系, 是多个不相关进程并发操作共享内存 2 共享内存一开始不存在, 由第一个访问他的进程创建 3 当共享内存退出时, 由最后一个离开的进程释放共享内存, 并清除信号量 在这个问题之中, 主要有两个比较大的问题: 1 怎样新建并初始化共享内存 新建共享内存的数据都可以用信号量来控制,

Windows环境下共享内存通信

一.引言 在Windows程序中,各个进程之间常常需要交换数据,进行数据通讯.WIN32 API提供了许多函数使我们能够方便高效的进行进程间的通讯,通过这些函数我们可以控制不同进程间的数据交换. 进程间通讯(即:同机通讯)和数据交换有多种方式:消息.共享内存.匿名(命名)管道.邮槽.Windows套接字等多种技术."共享内存"(shared memory)可以定义为对一个以上的进程是可见的内存或存在于多个进程的虚拟地址空间.例如:如果两个进程使用相同的DLL,只把DLL的代码页装入内存

Windows上CAtlFileMapping共享内存的使用以及内部机制

前言: 使用CEF载入网页.做JS与C++交互时.须要向主窗体发送一些消息来通知界面做对应的处理.可是,因为CEF使用chrome内核是多进程架构的.渲染引擎与主程序都不在同一个进程里面.因此.理所当然的就想到了使用共享内存了.为了更easy地使用,我们选择的是ATL里面封装的共享内存操作类:CAtlFileMapping. CAtlFileMapping使用: 定义结构体,包括你所须要共享的数据,这里我们仅仅须要共享主窗体的句柄 //自己定义进程共享数据结构体 struct PROCESS_S

共享内存的设计

一.服务器构架 一个天龙八部游戏区,主要服务器部署情况如下图所示: 实际部署可能有所不同.区角色数据库可以安装到Machine4,那么一个区有5台物理机器.LoginServer和WorldServer.CharacterDB.BillingServer有连接.WorldServer和各个GameServer有连接.ShareMemory和CharacterDB有连接. 一台物理机器上,会启动一个ShareMemory进程和一个服务器进程,服务器进程有世界服务器和游戏服务器.天龙八部的世界是Zo

PHP 共享内存使用与信号控制

共享内存 共享内存的使用主要是为了能够在同一台机器不同的进程中共享一些数据,比如在多个 php-fpm 进程中共享当前进程的使用情况.这种通信也称为进程间通信(Inter-Process Communication),简称 IPC. PHP 内置的 shmop 扩展 (Shared Memory Operations) 提供了一系列共享内存操作的函数(可能是用的人不多吧,这一块儿的文档还没有中文翻译).在 Linux 上,这些函数直接是通过调用 shm* 系列的函数实现,而 Winodows 上