1

我在父进程中有以下代码:

vector<vector<double> > matrix(n); /* matrix NxM */
/* pushing data */
HANDLE hMapping = CreateFileMapping(INVALID_HANDLE_VALUE,
    0, PAGE_READWRITE, 0, 2*sizeof(int) + sizeof(double)*n*m, lpName);

LPVOID lp = MapViewOfFile(hMapping, FILE_MAP_WRITE, 0, 0, 0);

mat_tmp* tmp = (mat_tmp*)lp;
tmp->n = n; tmp->m = m;
tmp->vv = vector<vector<double> >(matrix.begin(), matrix.end());

在一个子进程中,我试图接收这个向量>,但我的子进程每次都会终止。

LPTSTR lpName = _tcsdup(TEXT(map_name));
HANDLE hMapping = CreateFileMapping(INVALID_HANDLE_VALUE,
    0, PAGE_READWRITE, 0, 2*sizeof(int) + sizeof(double)*n*m, lpName);
LPVOID lp = MapViewOfFile(hMapping, FILE_MAP_WRITE, 0, 0, 0);

mat_tmp * tmp = (mat_tmp*)lp;
vector<vector<double> > matrix(tmp->vv.begin(), tmp->vv.end());

当我尝试使用matrix子进程中的数据时发生错误。小结构如下:

struct mat_tmp
{
    int n; int m; vector<vector<double> > vv;
};

如何在孩子身上正确接收我的载体?

4

3 回答 3

1

它不会按照您目前的方式工作。映射的内存将包含 n 和 m 以及向量类的内部结构,这可能是几个指针,具体取决于您的 STL 实现。紧随其后的是一堆垃圾。您将无法从其他进程安全地访问这些指针,因为它位于不同的地址空间中。

您需要将向量指向的内存实际复制到映射内存中并在另一侧重建向量。

此外,您需要的内存大小不会是 sizeof(int)*n*m。看起来你想在结构中有 2 个整数 n & m 和一个 n*m 双打的集合。

因此,分配 2*sizeof(int) + n*m*sizeof(double)。将 n & m 复制到内存中,然后将矩阵的行复制到其中。在接收端,读取 n & m,然后将数据反序列化为向量向量。

也许使结构像这样:

struct mat_tmp
{
    int n; int m; double vv[1];
};

然后,直接复制到共享内存中:

double* dst = tmp.vv;
for (size_t y = 0; y < matrix.size(); ++y) {
   memcpy(dst, &(matrix[y][0]), matrix[y].size()*sizeof(double));
   dst += matrix[y].size();
}

另一方面,

dst_matrix.resize(n);
for (size_t y = 0; y < n; ++y) {
    dst_matrix[y].resize(m);
    memcpy(&(dst_matrix[y][0]), tmp + (y * m), m * sizeof(double));
}

所有未经测试,可以做得更优化,但希望它更好地解释你需要做什么。

于 2012-12-20T13:15:21.007 回答
1

您需要覆盖向量的默认分配器对象,以便它完全在 MapView 的内存空间中工作,因为默认分配器对象将使用堆内存进行所有分配。Bjarne Stroustrup(C++ 的创建者)写了一篇非常古老的 Dr.Dobbs 文章,它准确地讲述了如何完成这项任务:

http://www.drdobbs.com/creating-stl-containers-in-shared-memory/184401639

于 2013-06-14T02:00:12.200 回答
0

这不起作用,向量只会保存一个指针,实际数据是堆分配的。您的 memcpy 仅复制指针,这在收件人一侧无效。

于 2012-12-20T13:26:18.930 回答