2017-03-18 40 views
8

Jeśli aplikacja wykonuje pewne operacje podnoszenia z wieloma deskryptorami plików (np. Otwarcie - zapisywanie danych - synchronizacja - zamykanie), co tak naprawdę dzieje się z uruchomionym środowiskiem wykonawczym? Czy blokuje wszystkie goroutiny w czasie, gdy występuje kosztowna syscall (jak syscall.Fsync)? Czy tylko wywołująca goroutine jest zablokowana, podczas gdy inne wciąż działają?Czy ma sens robienie drogich telefonów z różnych goroutines?

Czy ma sens pisanie programów z wieloma pracownikami, którzy zajmują dużo przestrzeni użytkownika - przełączanie kontekstu przestrzeni jądra? Czy ma sens stosowanie wzorców wielowątkowych do wprowadzania danych na dysku?

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

related: [Liczba wątków używanych przez idź wykonawczego] (http://stackoverflow.com/questions/39245660/number-of-threads-used-by- go-runtime/39246575 # 39246575). – icza

+1

Też się o to pytam i o czym rozmawiamy [tutaj] (https://groups.google.com/d/topic/golang-nuts/NXMTsgZ_In8/discussion). – kostix

Odpowiedz

3

Jeśli z bloków syscall, środowisko wykonawcze Go rozpocznie nowy wątek, tak że liczba wątków dostępny do uruchomienia goroutines pozostaje taka sama.

Pełniejsze wyjaśnienie można znaleźć tutaj: https://morsmachine.dk/go-scheduler