2012-02-09 16 views
19

配列をMmap経由でファイルにマップしようとしていますが、配列はfloat64のような任意の型にできます。 Cでは、私はこれを見つけるone。いくつかのテキストを読んだ後、私はこれを書いたsample。私はそれが正しいのか分からず、ファイルに値を書き込んでいません。配列のサイズを1000から10000のように大きくすると、クラッシュします。もし誰かがそれを正しく行う方法を知っていたら、教えてください。GoでMmapを使用してファイルに配列をマッピング

ありがとうございます!

答えて

25
たとえば

、あなたのサンプルプログラムを見直し、

package main 

import (
    "fmt" 
    "os" 
    "syscall" 
    "unsafe" 
) 

func main() { 
    const n = 1e3 
    t := int(unsafe.Sizeof(0)) * n 

    map_file, err := os.Create("/tmp/test.dat") 
    if err != nil { 
     fmt.Println(err) 
     os.Exit(1) 
    } 
    _, err = map_file.Seek(int64(t-1), 0) 
    if err != nil { 
     fmt.Println(err) 
     os.Exit(1) 
    } 
    _, err = map_file.Write([]byte(" ")) 
    if err != nil { 
     fmt.Println(err) 
     os.Exit(1) 
    } 

    mmap, err := syscall.Mmap(int(map_file.Fd()), 0, int(t), syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED) 
    if err != nil { 
     fmt.Println(err) 
     os.Exit(1) 
    } 
    map_array := (*[n]int)(unsafe.Pointer(&mmap[0])) 

    for i := 0; i < n; i++ { 
     map_array[i] = i * i 
    } 

    fmt.Println(*map_array) 

    err = syscall.Munmap(mmap) 
    if err != nil { 
     fmt.Println(err) 
     os.Exit(1) 
    } 
    err = map_file.Close() 
    if err != nil { 
     fmt.Println(err) 
     os.Exit(1) 
    } 
} 
+1

おかげで、PeterSO、それが働いています。 Goでmmapを使用するのが安全かどうか知っていますか? – tfmoraes

+5

「安全」とはどういう意味ですか?それはポインタを再作成し、したがって "安全でない"パッケージを必要とします。ポインタを正しく処理しないと、クラッシュする可能性があります(GAEでは、安全でないパッケージを使用するパッケージは一切許可しません)。しかし、それらを正しく処理すれば、高速かつ効率的なプログラムを書くことができます。 Russ Cox(Goの作者の一人)の[codesearch](http://code.google.com/p/codesearch/)アプリもmmapを多く使用しているので、インスピレーションのためにそれを見てみるとよいでしょう。 – tux21b

+1

@ tux21b:例えば、 Go GAEの数学パッケージ?参照してください[リンク](http://golang.org/src/pkg/math/unsafe.go) – zzzz

関連する問題