我正在尝试从文件中读取和写入。 为了同时写入文件,我创建了以下函数:
func write(f *os.File, b []byte, off int64, c chan int) {
var _, err = f.WriteAt(b, off)
check(err)
c <- 0
}
然后我创建一个文件和100000个goroutine来执行写操作。
它们每个都将一个16384
字节数组写入硬盘:
func main() {
path := "E:/test"
f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0666)
check(err)
size := int64(16384)
ones := make([]byte, size)
n := int64(100000)
c := make(chan int, n)
for i := int64(0); i < size; i++ {
ones[i] = 1
}
// Start timing
start := time.Now()
for i := int64(0); i < n; i++ {
go write(f, ones, size*i, c)
}
for i := int64(0); i < n; i++ {
<-c
}
// Check elapsed time
fmt.Println(time.Now().Sub(start))
err = f.Sync()
check(err)
err = f.Close()
check(err)
}
在这种情况下,写入大约1.6 GB,其中每个goroutine写入非重叠字节范围。 io
包的文档指出Clients of WriteAt can execute parallel WriteAt calls on the same destination if the ranges do not overlap.
所以我期望看到的是,当我使用go write(f, ones, 0, c)
时,由于所有写操作都在相同的字节范围内,因此需要更长的时间。
然而,经过测试,我的结果非常出乎意料:
使用go write(f, ones, size*i, c)
平均约为3s
但使用go write(f, ones, 0, c)
的平均值只有约480ms
我是否以错误的方式使用WriteAt功能?如何实现对非重叠字节范围的并发写入?