Chinaunix

标题: 用mmap共享内存 进行进程间通信出现问题 [打印本页]

作者: datastreamcn    时间: 2008-12-30 00:58
标题: 用mmap共享内存 进行进程间通信出现问题
fd_map=open(path, O_CREAT|O_RDWR|O_TRUNC, 00777);
write(fd_map," ", sizeof(CPipegData));

pmap = (CPipeData*) mmap( NULL,sizeof(CPipeMsgData), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );


pMsg->dwPduLenth = pmap->Msgdata.msgLenth;
if(pmap->Msgdata.pMsgData && pMsg->dwPduLenth != 0)

{
    pMsg->pMsgBuf = new unsigned char[pMsg->dwPduLenth + 1];
    memcpy(pMsg->pMsgBuf, pmap->Msgdata.pMsgData, pMsg->dwPduLenth);
    pMsg->pMsgBuf[pMsg->dwPduLenth] = '\0';
}



我的问题:
1、为什么要加上write(p_msg_map," ", sizeof(CPipeMsgData));进程才能对内存进行写操作?
2、还有我的代码把数据用memcpy到一个对象的成员中,然后把pMsg 的指针的指针保存到msgTempList中,这样push_back多个后,一次性把msgTempList中的数据全部取得,到另外一个跟msgTempList同样类型的list中,在对单个数据操作,把pmsgBuf
指向一个unsigned char* 指针,就出现段错误,但是我确定memcpy(pMsg->pMsgBuf, pmap->Msgdata.pMsgData, pMsg->dwPduLenth);中的pmap->Msgdata.pMsgData 是有数据的啊, 请各位帮我看看!谢谢
作者: xiexiecn    时间: 2008-12-30 11:11
标题: 回复 #1 datastreamcn 的帖子
->fd_map=open(path, O_CREAT|O_RDWR|O_TRUNC, 00777);
path是啥?普通文件?已经存在了?
->write(fd_map," ", sizeof(CPipegData));
有问题," "才一个字节,sizeof(CPipegData)是多少?
第二个问题太长了,看了眼花...,你先仔细man mmap看看帮助吧。
作者: datastreamcn    时间: 2008-12-30 15:59
先谢谢楼上兄弟,
1、 path是普通文件,我认为存在与否应该没有关系。
  write是要写上数据。

  2、我的第二个问题我确认是在对stl 中的list操作问题上,就是先把数据 添加到一个CMSGLIST list1,list2, 然后从list1中取出数据到list2中来,然后对里面的数据进行访问就失败,查看是NULL。
我能确定memcpy(pMsg->pMsgBuf, pmap->Msgdata.pMsgData, pMsg->dwPduLenth);  中的pmap->Msgdata.pMsgData是有数据的,操作后,
  (1)在addMsg(pmsg) 函数中 list1.push_back(pMsg )   添加
   (2)在getAll(CMSGLIST & list2)  中把list1中的数据拷贝到list2中,然后访问list2中第一个元素的pMsgBuf ,段错误,pMsgBuf为NULL。

附注:

class CMsg
{
     ..........
     int    dwPduLenth;
     unsigned char *pMsgBuf;
}
typedef std::list<CMsg *>  CMSGLIST;


请各位不吝指教?谢谢
作者: datastreamcn    时间: 2008-12-30 17:22
谢谢各位兄弟了!
问题2已经解决,是我自己不小心,没有赋值。

  对于问题1,

CPipegData msgData;
fd_map=open(path, O_CREAT|O_RDWR|O_TRUNC, 00777);
write(fd_map, (void*)&msgData, sizeof(CPipegData));  

pmap = (CPipeData*) mmap( NULL,sizeof(CPipeMsgData), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );



我也看了mmap的Manual上的,感觉还是不怎么清楚, 我写了个小测试程序,如果屏蔽掉write 语句,就会报总线错误?
还有点不怎么明白?为什么要加上这条语句了,或者还有其他什么办法不加write语句没?

   请各位兄弟姐妹指点指点,本人在刚做linux开发,以前是在windows 下开发,再此感谢!
作者: foochow    时间: 2008-12-30 17:37
扩大文件大小啊。或者用ftruncate来扩充你的文件。。去看看UNIX网络编程第二卷,讲得很详细了
作者: converse    时间: 2008-12-30 18:23
1.write函数可以预先分配sizeof(CPipeMsgData)这么大的一个文件,这样才能mmap映射上去.
作者: datastreamcn    时间: 2008-12-31 00:26
谢谢各位了!

因为我看到apue上面在用mmap的时候没有要write一下,还有看了帮助认为mmap函数中的第二个参数就可以直接为文件分配len长的文件。呵呵,看来以后要很仔细的看帮助文档,呵呵!
  
再次谢谢各位了!




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2