На Gopher Meetup на станции Ханчжоу Хуан Цинбин из NetEase поделился относительно простой темой — «Визуальное обучение и параллельное программирование». Ниже приводится стенограмма его речи.
Go создан для параллелизма. Короче говоря, я думаю, что параллелизм можно рассматривать как способ построения программ, как показано на следующем рисунке.
Параллельность и параллелизм
Чтобы понять разницу между параллелизмом и параллелизмом, рекомендуется прочитать раздел Роба Пайка (нажмите, чтобы прочитать исходный текст, чтобы перейти). В этом видео он объяснил процесс параллелизма Go с яркой анимацией Gopher.
Резюмируя свои взгляды следующим образом:
-
Параллелизм — это мощно
-
Параллелизм помогает достичь параллелизма, упрощает параллелизм (масштабирование и т. д.).
-
Параллелизм — это не параллелизм, параллелизм фокусируется на архитектуре, параллелизм фокусируется на выполнении, они разные, но связаны.
Потому что сегодня в центре внимания не теория, а демонстрация параллельного процесса с визуальной точки зрения. Поэтому совмещение этих двух наглядных графов позволяет интуитивно понять разницу между параллелизмом и параллелизмом, ведь картинка стоит тысячи слов. (Пожалуйста, скопируйте ссылку, чтобы открыть ее в браузере)
-
Параллелизм: http://talks.bingohuang.com/2017/go-concurrency-visualize/pingpong36.html
-
Параллелизм: http://talks.bingohuang.com/2017/go-concurrency-visualize/parallelism.html.
В общем, параллелизм — это метод программирования, который выполняет (обычно связанные) вычислительные задачи одновременно, когда два или более события происходят одновременно; в то время как параллелизм — это метод программирования, который объединяет независимые процессы выполнения, два или несколько событий происходят внутри тот же интервал времени.
Зачем заботиться о параллелизме?
Сегодня эра многоядерного параллельного мира. Закон Мура постепенно перестает работать, и необходимо уделять больше внимания идеям параллельного программирования.
Но параллельное программирование — непростая задача, и в Go есть хорошая поддержка параллелизма.
Параллелизм в Go
Горутина - параллельное выполнение
-
Подобно & в UNIX
-
Похож на нити, но легче
-
Горутина — это функция, которая работает независимо
-
Когда горутина блокируется, ее поток блокируется, но другие горутины не затрагиваются.
Создайте горутину с ключевым словом go следующим образом:
Channel
-
Подобно каналам в UNIX
-
Это позволяет передавать сообщения между горутинами
Ниже приведен простой пример, который представляет собой обычный таймер, и позже его также можно превратить в наглядный график.
Select
-
Аналогично обычному переключателю в языке
-
Но его условие суждения основано на общении, а не на эквивалентном сопоставлении, основанном на ценности.
Go упрощает параллельное программирование
Но тут возникает проблема:
-
Как объяснить параллелизм в Go?
-
Что мы думаем о параллельных процессах в Go?
-
В конечном счете, как мы можем лучше практиковать параллельное программирование в Go?
Вот волшебное оружие — GoTrace, инструмент с открытым исходным кодом, который может визуализировать параллельный процесс Go с божественного дивана. В основном это две программы:
-
gotrace (go): анализировать результат выполнения трассировки инструмента go
-
gothree (js): создание 3D-изображений на основе ThreeJs и WebGL.
Спасибо God Divan за предоставление этого инструмента и множества материалов по параллельному режиму Go.
видеть значит верить
1.Hello,World!
Неважно, на каком языке написано, оно начинается с hello world, код очень простой — один канал, одна горутина, один раз написать, один раз прочитать.
Эффект следующий (скопируйте ссылку http://talks.bingohuang.com/2017/go-concurrency-visualize/helloworld.html, которую можно открыть в браузере или получить доступ напрямую):
Здесь синяя линия представляет горутину, работающую во времени. Тонкая синяя линия соединяет «main» и «# 20», отмечая начало и конец горутин, показывая их отношения родитель-потомок. Наконец, красная стрелка показывает нам действие «отправить/получить». На самом деле это два отдельных действия, которые я пытался анимировать как одну транзакцию: отправить из А в Б. «#20» в имени горутины — это фактический внутренний идентификатор горутины, каким-то образом полученный из среды выполнения.
2. Таймер
Помните, что пример таймера, данный Channel, также очень типичен — создайте канал, запустите горутину, запишите данные в канал через заданный интервал времени, а затем верните канал вызывающей функции. Вызывающий блокируется на фиксированное время, чтобы прочитать канал. Давайте запустим 24 таких таймера и попробуем визуализировать их.
Взгляните на эффект (скопируйте ссылку http://talks.bingohuang.com/2017/go-concurrency-visualize/timer.html):
Очень образно, не так ли?
3. Настольный теннис
два игрока
Взгляните на эффект (скопируйте ссылку http://talks.bingohuang.com/2017/go-concurrency-visualize/pingpong2.html, чтобы открыть ее в браузере)
Рекомендуется открыть указанную выше ссылку в браузере ПК, чтобы вы могли взаимодействовать с анимацией WebGL и играть. Вы можете замедлить, ускорить и увидеть его с разных сторон.
три игрока
Вышеизложенное представляет собой обычный процесс борьбы двух игроков в настольный теннис. Что было бы, если бы игроков было трое? Теперь давайте попробуем, запустив 3 спортсменов. В коде требуется лишь небольшая модификация, и можно добавить игрока:
Результаты следующие :( http://talks.bingohuang.com/2017/go-concurrency-visualize/pingpong3.html скопируйте ссылку в открытый браузер)
36 игроков
Давайте рассмотрим более сложный пример, в котором участвуют 36 спортсменов.
Эффект (скопируйте ссылку http://talks.bingohuang.com/2017/go-concurrency-visualize/pingpong36.html, откройте в браузере)
Здесь мы видим, что каждый спортсмен ходит по очереди, вам может быть интересно, почему? Почему горутины ловят мяч в таком строгом порядке?
Ответ заключается в том, что среда выполнения Go поддерживает очередь «первым пришел – первым обслужен» (FIFO) для получателей (горутин, которые готовы получать сообщения из определенного канала), и в нашем случае каждый игрок попадает за стол именно тогда, когда он нажимает мяч быть готовым, когда.
4. Вулнесе экран
Вышеуказанные немногие примеры относительно простых, давайте посмотрим на более сложный одновременный алгоритм: алгоритм сита Prime Number, также известный как алгоритм Eratosthenes, представляет собой древний алгоритм нахождения меньшего или равным данному целому числу. Основная идея алгоритма: первое с наименьшим простым числом на экран, выбросив кратные 2; а является следующим простым числом другого не сито (здесь 3). Prime Number 3, а затем Go Sieve, сито, чтобы избавиться от нескольких трех ... так постоянно повторяется до конца экрана.
Параллельным вариантом этого алгоритма является использование горутин для фильтрации чисел — одна горутина находит простое число, а каналы используются для передачи чисел от генератора к фильтру. Когда простое число найдено, оно передается в main по каналу, а затем выводится.
Конечно, этот алгоритм не очень эффективен, особенно если вы пытаетесь найти много простых чисел и ищете наименьшую сложность большого O, но он очень элегантен.
Вы можете взглянуть на визуализацию (http://talks.bingohuang.com/2017/go-concurrency-visualize/primesieve.html)
Вы можете испытать анимацию в интерактивном режиме. Его графический способ помогает нам лучше понять алгоритм. Горутина функции генерации выдает каждое целое число, начиная с 2. И каждая новая горутина функции фильтра будет фильтровать числа, кратные определенному простому числу - 2, 3, 5, 7... Первое число каждого фильтра является простым числом, отправляет его в основную функцию и выводит. Если вы повернете изображение и посмотрите сверху вниз, вы увидите, что все числа, отправленные из горутины в main, являются простыми числами.
Очень изящный алгоритм, особенно с 3D-изображениями.
5. Другое — утечка горутин
Хотя Goroutine — очень легкий поток, его не следует тратить впустую. Что, если утечек больше, чем N горутин?
Посмотрите на эффект http://talks.bingohuang.com/2017/go-concurrency-visualize/leak.html
Выглядит красиво, но это бомба замедленного действия, поэтому обязательно обращайте внимание на утечки Goroutine при написании кода.
Введение в использование Gotrace
Наконец, давайте поговорим об использовании GoTrace, исходный код которого также является открытым.
Способ загрузки: go get -v -u github.com/divan/gotrace
Ветка по умолчанию (мастер) основана на разработке Go 1.6, я рекомендую переключиться на ветку Go18, которая поддерживает Go 1.8.
Конкретное использование заключается в следующем:
Эффект от прямого запуска go-кода не очень хороший, рекомендуется генерировать трассировку, которую нужно добавить до и после исполняемого кода:
В сочетании с докером можно использовать следующие скрипты:
Он автоматически откроет этот браузер, вы можете настроить угол обзора, вы можете масштабировать, вращать, выделять жирным шрифтом, менять изображение.
сцены, которые будут использоваться
Наконец, я хочу поговорить о сценариях использования. Прежде всего, когда я увидел это, я подумал, что это очень круто. Это вызовет у всех интерес к изучению Go. В то же время его также можно использовать для изучения режима параллелизма Go и изучения процесса параллелизма Go. Я надеюсь, что это будет быть полезным для всех, чтобы продолжить изучение языка Go.