Многозадачность в «Гоу»
В прошлой своей записи я упомянул многозадачность в «Гоу», а сейчас вспомнил, что я ни разу не показывал как же она там выглядит с точки зрения простого программиста. Покажу на примере.
Предположим, нам нужно вычислить
package main
import (
"io"
"os"
"crypto/sha512"
"encoding/hex"
"runtime"
"strconv"
)
func main () {
ch := make(chan string)
N := 3
runtime.GOMAXPROCS(N)
for i := 0; i<N; i++ {
go func (name string, num int, ch chan string) {
if f, err := os.OpenFile(name, os.O_RDONLY, 0666); err == nil {
defer f.Close()
h := sha512.New()
io.Copy(h, f)
ch <- strconv.Itoa(num) + ". " + hex.EncodeToString(h.Sum())
} else {
panic("Cannot open file")
}
}(os.Args[0], i, ch)
}
for ; N > 0; N-- {
print(<-ch, "\n")
}
}Что здесь происходит.
Первая строка объявляет имя модуля, для основного модуля программы это имя должно быть «main», эта конструкция скажет компилятору, что именно тут находится входная точка нашей программы. На первый взгляд кажется, что в основном модуле можно было бы просто не указывать имя, но язык придерживается хорошего принципа «явное лучше неявного», чем он мне очень симпатичен.
Дальше, очевидно, подключаются модули, в языке базовых функций почти нет, поэтому даже для такой небольшой программы мне понадобилось шесть модулей: «io» для копирования данных из одного потока в другой, «os» для работы с файлом, «crypto/sha512» для хеширования, «encoding/hex» для кодирования получившейся
Функция main — входная точка основного модуля программы, именно она (как в «Си») вызывается в самом начале.
Далее я создаю (make) небуферизированный «канал» и объявляю, что по нему будут идти строки, конструкция «:=» многим напоминает Паскаль, но отношения к нему не имеет, это синтаксический сахар для создания локальной переменной. «Канал» — это хорошее, говорящее название, хорошо отображающее суть, это действительно канал общения
В цикле создаются и сразу запускаются в фоне (конструкцией «go») на выполнение N
Внутри
Цикл не ждёт выполнения
Дальше идёт второй цикл, где N раз запускается команда на чтение из канала („… <- ch»).
Чтобы убедиться, что
У такой лёгкости использования есть свои ограничения, но об этом
Комментарии 15
жалко хардов с несколькими ядрами нет.
SSD
Женя, а Forth ты учил?
Учил, но очень давно, в детстве ещё. Мне тогда он очень нравился.
Комментарий для www.orcinus.ru:
Go, Python, JavaScript, Lua, PowerShell.
Когда-то ещё Sphinx С-- нравился, я был ещё адептом экономии всего и вся, ещё время от времени писал на ассемблере x86. Сейчас использовать мне его просто негде, не нужна такая жёсткая экономия, а более ценно для меня моё собственное время. Разве только для развлечения и отдыха что-то на нём написать.
А какие задачи ты решаешь на PowerShell?
Уже никакие (Винды нет), раньше всё подряд писал, автоматизацию всякую и прочее. Немного писал об этом в блоге: https://bolknote.ru/?powershell
Комментарий для www.orcinus.ru:
да используются. помогает оно исключительно в плане скорости. т.е. быстрее чтение запись, меньше пересечений. если каждый винт выделить для отдельного приложения — быстрее гораздо.
sas контролёр даже есть, хотя именно в плане скорости и параллельности — полное разочарование, деньги на ветер.
это тоже только скорость.
Комментарий для zg.livejournal.com:
Это не просто скорость, это скорость произвольного доступа, вот что важно. Там нет механической читающей головки и блинов, которые спозиционировать надо.
вы утверждаете, что ссд — это харды с несколькими ядрами. это означает как минимум для меня возможность истинно параллельного чтения/записи. где оно в ssd, я не вижу.
Комментарий для zg.livejournal.com:
Нет, я утверждаю, что в SSD проблема параллельного чтения стоит менее остро.
интересно твое мнение :)