LINUX.ORG.RU

Go: особенности работы рантайма во время вызова дорогих syscall

 ,


1

5

Всем привет. Буду благодарен, если кто-то сможет прояснить, как именно ведёт себя рантайм Go при выполнении медленных сисколлов. Представим, что есть приложение, которое выполняет интенсивную работу с ФС (создаёт, пишет, синкает файлы). По очевидным причинам вызов 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
		}

		f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, os.FileMode(0644))
		if err != nil {
			log.Fatal(err)
			continue
		}

		if _, err := f.Write(data); err != nil {
			log.Fatal(err)
			continue
		}

		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()
}

Спасибо всем за помощь.

Если я верно помню то поток ОС на котором запущена гороутина блокируется и в Go-планировщик добавляется новый поток чтобы крутить остальные гороутины.

urxvt ★★★★★ ()
Ответ на: комментарий от ei-grad

Русская версия легко находится во вконтакте.

Документация (пускай даже перевод) в вконтакте? Новое дно пробито смузеводами.

Chaser_Andrey ★★★★★ ()

Go автоматически все разрулит и будет работать быстрее Java!

anonymous ()

В Linux нет нормальной асинхронной работы с файлами, поэтому ее эмулируют созданием пула потоков, выполняющих операции ввода-вывода.

имеет ли смысл применять многопоточность для ввода на диск?

именно так и нужно делать.

anonymous ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.