免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3883 | 回复: 0
打印 上一主题 下一主题

linux STL 能够共享内存的实现 专家见解 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-10-28 12:57 |只看该作者 |倒序浏览
//============================================================================
// Name        : tst.cpp
// Author      : xiangxianhan
//============================================================================

#include <iostream>
#include <map>
#include <wait.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <exception>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>

using namespace std;

/////////定义外部共享机制///////////////
const key_t ipckey = 24568; //实时
const int perm = 0666; //实时路况可以被任何进程读写
size_t shmSize = 4096; //实时路况的大小
int shmId; //实时路况共享ID

void* rp; //实时路况共享内存引用
typedef map<int, int> MAP1; //第一个map
typedef map<int, MAP1*> MAP2; //第二个map
typedef map<int, MAP2*> MAP3; //第三个map

int main() {
    //启动共享机制
    if ((shmId = shmget(ipckey, shmSize, IPC_CREAT | IPC_EXCL | perm)) == -1) //创建和取得已有的共享内存
    {
        if ((shmId = shmget(ipckey, shmSize, 0)) == -1) {
            perror("shmget\n");
            exit(1);
        }
    }

    ////////////////第一个进程写入数据/////////////////////
    pid_t pd1 = -1;
    if ((pd1 = fork()) == 0) {
        MAP3 * gmap;

        try {
            rp = (void*) shmat(shmId, NULL, 0);//告诉当前进程使用它,也就映射到当前进程空间中
        } catch (std::exception& e) {
            printf("shmat Standard exception: %s\n", e.what());
        }
        try {
            gmap = new (rp) map<int, MAP2*> ;//把它附加给共享数组使用
        } catch (std::exception& e) {
            printf("new (rp2) Standard exception: %s\n", e.what());
        }

        MAP2 *mp2 = new MAP2;
        MAP1 *mp1 = new MAP1;
        mp1->insert(pair<int, int> (mp1->size(), 10));
        mp2->insert(pair<int, MAP1*> ((int) mp2->size(), mp1));
        gmap->insert(pair<int, MAP2*> ((int) gmap->size(), mp2));
        printf("第一个进程 第三个map插入完毕 大小 %d\n", (int) gmap->size());
//        msync(rp,sizeof(gmap),2);
//        sync();
        shmdt(rp);
        sleep(5);
        printf("第一个进程推出\n");
//        exit(1);
    }

    ////////////////第二个进程读取数据/////////////////////
    pid_t pd2 = -1;
    if ((pd2 = fork()) == 0) {
        MAP3* gmap2 = (map<int, MAP2*>*) shmat(shmId, NULL, 0);//当前进程可用

        while (true) {
            MAP3::iterator iter = gmap2->begin();
            printf("第二个进程 第三个map读取 大小 %d\n", (int) gmap2->size());
            for (; iter != gmap2->end(); iter++) {
                MAP2 *mp = iter->second;
                printf("第二个进程 第二个map读取 大小 %d\n", (int) mp->size());
                MAP2::iterator iter1 = mp->begin();
                for (; iter1 != mp->end(); iter1++) {
                    MAP1 *tm = iter1->second;
                    printf("第二个进程 第一个map读取 大小 %d\n", (int) tm->size());
                    MAP1::iterator tm2 = tm->begin();
                    for (; tm2 != tm->end(); tm2++) {
                        printf("第二个进程 第一个map读取到值  %d\n", tm2->second);
                    }
                }
            }
            sleep(1);
        }
    }

    //等待子进程结束。
    pid_t pid_ret; //杀死后返回的id
    int nstat; //杀死进程的状态码
    while ((pid_ret = waitpid(-1, &nstat, 0)) > 0) {
    }

    //取消内存共享
    shmdt(rp);
    shmctl(shmId, IPC_RMID, NULL);//系够的时候调用它释放

    return 0;
}

运行的结果是:

第一个进程 第三个map插入完毕 大小 1
第二个进程 第三个map读取 大小 1
第一个进程推出
第二个进程 第三个map读取 大小 1
第二个进程 第二个map读取 大小 1
第二个进程 第一个map读取 大小 1
第二个进程 第一个map读取到值  10


个人问题:stl有自己的申请内存的机制,但通过以上有希望改变它自己的机制使得stl的指针成为共享内存。原因是当第一个没有走到结束时,第二进程访问不到第一个进程的下一个map的值的;然而当第一个进程结束时
(当然不能exit(0)或return推出,否则进程二也是访问不到的)时,第二个进程就能访问到第一个进程添加的值了。

解决的问题:怎么样让第一个进程不推出,第二个进程同样能访问到第一进程的指针。到底第一进程在退出的时候做了什么事情,导致第二个进程能共享它的指针。如果这个理论能实现那么STL就能在linux共享内存当中使用。

希望:专家能够解决这个问题或给出解决方向。不尽感激!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP