4

同じファイルのメモリマッピングを使用して、2つの異なるプロセスが通信できるようにしようとしています。しかし、私はこれに関していくつかの問題を抱えています。これは、open()呼び出しを使用して、ファイル記述子をmmapに渡す方法に関係していると感じています。

これが私のコードです、何か問題がありますか?

オブジェクト1のコード:

 16     FILE* temp = fopen(theSharedFileName, "w");
 17     fseek(temp, fileSize-1, SEEK_SET);
 18     fprintf(temp, "0"); // make the file a certain size
 19     fseek(temp, 0, SEEK_CUR);
 20 
 21     int sharedFileName = fileno(temp);
 ...
 31     sharedArea = (MyStruct*)mmap(0, fileSize,
 32         PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED, sharedFileName, 0);

オブジェクト1は一度だけ作成され、既存のデータをリセットしたいので、「w」ファイルモードを使用します。

オブジェクト2のコード:

 130     FILE* tempFile = fopen(sharedFileName, "a");
 131     int theFile = fileno(tempFile);
 ...
 135     sharedArea = (MyStruct*)mmap(NULL, fileSize,
 136         PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED, theFile, 0);
4

3 に答える 3

25

いくつかの問題:

  1. 高レベルのI/O(fopen()、fseek())とmmap()のような低レベルの操作を混在させないでください。fileno()を使用して低レベルのファイル記述子を取得できますが、これは同じ場所に到達するために最長のルートを使用するようなものです。また、mmap()を使用するだけで、BSDとPOSIXを超える互換性が失われるため、標準のCI/O関数を使用しても何も得られません。open()とlseek()を直接使用するだけです。
  2. メモリマッピングしているのと同じファイルでストリーム形式のI/O(fprintf())を使用することは意味がありません。ファイルをメモリマップする場合、ランダムアクセス(直接インデックス)データとして使用することをシステムに暗黙的に通知します。fprintf()はストリーム出力用であり、通常は順次アクセスに使用します。実際、可能ではありますが、同じ記述子にfprintf()とfseek()が表示されることはまれです(これは移植性さえありませんが、前の項目のため、移植性については考慮していません)。
  3. 保護は、開いているファイルの保護と一致する必要があります。「w」をfopen()とPROT_READ | PROT_WRITE | PROT_EXECmmap()に渡しているため、この制限に違反しています。これは、高レベルのI / Oとメモリマッピングを混在させてはいけない理由も浮き彫りにしますfopen(...,"w")。正しいフラグでファイルを開くことをどのように保証しますか?これは、Cライブラリの「実装-詳細」であると想定されています。読み取りおよび書き込み権限を持つファイルをメモリマップする場合は、低レベルを使用しopen(theSharedFileName, O_RDWR)てファイルを開く必要があります。
  4. 一緒に使用PROT_WRITEないでください。PROT_EXECポータブルではなくセキュリティ上のリスクがあります。W^X実行可能スペース保護について読んでください。
于 2009-04-12T23:32:01.063 に答える
2

他の人が言っているように、これにはfopen()やfriendsを使用しないでください。

発生している問題の一部は、fprintf()がストリームバッファを持つ可能性があるため、実際にはファイルを変更しない可能性があり、したがって、予期されたときに他のプロセスに表示される可能性があります。fflush()を追加することもできますが、read()とwrite()はアプリケーションレベルのバッファリングを行わないため、これらがより適している理由の1つです。

于 2009-04-13T00:03:03.360 に答える
2

C ++と、低レベルの詳細から保護し、IPCの抽象化を容易にするACEBoostなどのライブラリを使用できる場合。

于 2009-04-13T01:31:01.637 に答える