- 论坛徽章:
- 0
|
//============================================================================
// 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共享内存当中使用。
希望:专家能够解决这个问题或给出解决方向。不尽感激! |
|