2

ファイル記述子(をサポートする)を「偽造」する必要があり、fstatこのようにします。

func ScanBytes(b []byte) error {
  size := C.size_t(len(b))
  path := C.CString("/bytes")
  fd := C.shm_open(path, C.O_RDWR|C.O_CREAT, C.mode_t(0600))
  defer C.shm_unlink(path)
  defer C.close(fd)

  res := C.ftruncate(fd, C.__off_t(size))
  if res != 0 {
    return fmt.Errorf("could not allocate shared memory region (%d)", res)
  }

  var addr = unsafe.Pointer(&b[0])
  C.mmap(addr, size, C.PROT_READ|C.PROT_WRITE, C.MAP_SHARED|C.MAP_FIXED, fd, 0)
  defer C.munmap(addr, size)

  // _, err := syscall.Write(int(fd), b)

  return doSomethingWith(fd)
}

ファイル ハンドルへの書き込みがコメント アウトされている場所がわかります。

割り当てられた領域にバッファーを書き込まないと、空になります。mmapと組み合わせてMAP_FIXED、提供されたバッファーのアドレスを使用して、コンテンツをその領域にマッピングすることを望んでいました。

write呼び出しがコピーされるため、メモリ使用量が2倍になると思います。私は本当にしなければならないのwriteですか?

4

1 に答える 1

3

あなたが望むのは、コピーせずにファイル記述子を介して既存のメモリ領域にアクセスできるようにすることです。

この問題は、 mmap に関するこの以前のスタックオーバーフローの質問と非常によく似ています。

その答えに追加することはあまりありません。の割り当てを制御できないため、コピーなしでこれを行うことはできませんb。コピーが必要であることを認めれば、shm ソリューションは適切です。mmap は必要ありません。

mmap の man ページから、の定義MAP_FIXED:

指定されたものとは異なるアドレスをシステムが選択することを許可しないでください。指定されたアドレスが使用できない場合、mmap() は失敗します。MAP_FIXED が指定されている場合、addr はページサイズの倍数でなければなりません。MAP_FIXED 要求が成功した場合、mmap() によって確立されたマッピングは、addr から addr + len までの範囲のプロセスのページの以前のマッピングを置き換えます。このオプションの使用は推奨されません。

unsafe.Pointer(&b[0])特に基になる配列が小さい場合は、ページ サイズの倍数ではない可能性があります。その場合、 mmap は失敗します。いつものように、戻り値を確認してください

mmap が成功した場合、マッピングは以前のマッピングを置き換えます。つまり、データは失われます。スライスを読み取ると、バイトがゼロになります。

于 2013-11-26T17:06:15.333 に答える