2017-03-18 4 views
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

+0

関連:[囲碁ランタイムによって使用されるスレッドの数](http://stackoverflow.com/questions/39245660/number-of-threads-used-by- go-runtime/39246575#39246575)。 – icza

+1

[こちら](https://groups.google.com/d/topic/golang-nuts/NXMTsgZ_In8/discussion)にも尋ねられ、議論されています。 – kostix

答えて

3

システムコールをブロックした場合ゴルーチンを実行するのに使用可能なスレッドの数が同じで残るように、ゴーランタイムは、新しいスレッドを起動します。

充実説明はここで見つけることができます:https://morsmachine.dk/go-scheduler

関連する問題