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

デフォルトのアロケーター オブジェクトはすべての割り当てにヒープ メモリを使用するため、MapView のメモリ空間で完全に機能するように、ベクターのデフォルトのアロケーター オブジェクトをオーバーライドする必要があります。Bjarne Stroustrup (C++ の作成者) が書いた非常に古い Dr.Dobbs の記事があり、このタスクを達成する方法を正確に説明しています。

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

于 2013-06-14T02:00:12.200 に答える
1

現時点であなたがやっている方法ではうまくいきません。マップされたメモリには n & m とベクトル クラスの内部構造が含まれます。これは、STL 実装に応じて、おそらくいくつかのポインターになります。ジャンクの負荷が続きます。別のアドレス空間にあるため、他のプロセスからこれらのポインターに安全にアクセスすることはできません。

ベクトルが指すメモリを実際にマップされたメモリにコピーし、反対側でベクトルを再構築する必要があります。

さらに、必要なメモリのサイズは sizeof(int)*n*m にはなりません。構造体に 2 つの ints n & m と n*m double のコレクションが必要なようです。

したがって、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 に答える
0

これは機能しません。ベクトルはポインタのみを保持し、実際のデータはヒープに割り当てられます。memcpyはポインタのみをコピーしますが、これは受信者側では無効です。

于 2012-12-20T13:26:18.930 に答える