8
アプリケーションが複数のファイル記述子を使用して重労働を起こしている場合(例:データの同期を開始してデータを同期する)、実際に実行時に何が起こりますか?高価なシステムコール(例えばsyscall.Fsync
など)が発生した時点で、すべてのゴルーチンをブロックしていますか?または、他の人がまだ動作している間は、呼び出し側のゴルーチンだけがブロックされますか?異なるゴルーチンから高価なシステムコールを作るのは意味がありますか?
カーネルスペースのコンテキスト切り替えのように、多くのユーザー空間を占める複数のワーカーでプログラムを書くのは意味がありますか?ディスク入力にマルチスレッドパターンを使用するのは理にかなっていますか?
package main
import (
"log"
"os"
"sync"
)
var data = []byte("some big data")
func worker(filenamechan chan string, wg *sync.waitgroup) {
defer wg.done()
for {
filename, ok := <-filenamechan
if !ok {
return
}
// open file is a quite expensive operation due to
// the opening new descriptor
f, err := os.openfile(filename, os.o_create|os.o_wronly, os.filemode(0644))
if err != nil {
log.fatal(err)
continue
}
// write is a cheap operation,
// because it just moves data from user space to the kernel space
if _, err := f.write(data); err != nil {
log.fatal(err)
continue
}
// syscall.fsync is a disk-bound expensive operation
if err := f.sync(); err != nil {
log.fatal(err)
continue
}
if err := f.close(); err != nil {
log.fatal(err)
}
}
}
func main() {
// launch workers
filenamechan := make(chan string)
wg := &sync.waitgroup{}
for i := 0; i < 2; i++ {
wg.add(1)
go worker(filenamechan, wg)
}
// send tasks to workers
filenames := []string{
"1.txt",
"2.txt",
"3.txt",
"4.txt",
"5.txt",
}
for i := range filenames {
filenamechan <- filenames[i]
}
close(filenamechan)
wg.wait()
}
https://play.golang.org/p/O0omcPBMAJ
関連:[囲碁ランタイムによって使用されるスレッドの数](http://stackoverflow.com/questions/39245660/number-of-threads-used-by- go-runtime/39246575#39246575)。 – icza
[こちら](https://groups.google.com/d/topic/golang-nuts/NXMTsgZ_In8/discussion)にも尋ねられ、議論されています。 – kostix