2

ネットワーク ソケットから大量のデータを取得するための単純な「ディスクへのスピル」レイヤーを実装する必要があります。2 つの CFILE*ストリームが必要でした。1 つはファイルに書き込むバックグラウンド スレッドで使用され、もう 1 つはそれを読み取るフロント エンド スレッドで使用されます。

2 つのストリームは、ロックを取得して他のスレッドをブロックすることなく、一方のスレッドが一方のオフセットで書き込みを行い、他方のスレッドが別の場所で読み取りを行うことができるようにするためのものです。

ページング メカニズムがあるため、読み取り/書き込みはランダム アクセスの場所で行われます (必ずしもシーケンシャルである必要はありません)。

もう 1 つの注意点として、これは Windows と Linux で動作する必要があります。

質問: 最初のストリームへの fwrite が返された後、書き込まれたデータが 2 番目のストリームの fread にすぐに見えることが保証されますか?

そうでない場合、他にどのようなオプションを検討できますか?


そのため、Posix の pread/pwrite 関数が必要であることがわかりました。Win32 のバージョンは次のとおりです。

size_t pread64(int fd, void* buf, size_t nbytes, __int64 offset)
{
    OVERLAPPED ovl;
    memset(&ovl, 0, sizeof(ovl));
    *((__int64*)&ovl.Offset)=offset;

    DWORD nBytesRead;
    if (!ReadFile((HANDLE)_get_osfhandle(fd), buf, nbytes, &nBytesRead, &ovl))
        return -1;

    return nBytesRead;
}

size_t pwrite64(int fd, void* buf, size_t nbytes, __int64 offset)
{
    OVERLAPPED ovl;
    memset(&ovl, 0, sizeof(ovl));
    *((__int64*)&ovl.Offset)=offset;

    DWORD nBytesWritten;
    if (!WriteFile((HANDLE)_get_osfhandle(fd), buf, nbytes, &nBytesWritten, &ovl))
        return -1;

    return nBytesWritten;
}

(そして、これに関する意見を寄せてくれた皆さんに感謝します-非常に感謝しています)。

4

2 に答える 2

4

これは、メモリ マップド I/O に非常に適しているように思えます。一貫性があり、非常に高速であることが保証されており、複数のポインターを追跡するのは簡単です。

さまざまな OS でメモリ マッピングを設定するにはさまざまな関数が必要になりますが、実際の I/O は完全に移植可能です (ポインターの参照を使用)。

  • Linux: openmmap
  • 窓: CreateFileMappingMapViewOfFile
于 2011-03-10T02:02:16.277 に答える