Являются ли пулы goroutine go-langs просто зелеными нитями?

47

Комментатор здесь предлагает следующую критику зеленых нитей:

Первоначально я был продан на модели N: M как средство программирования, управляемого событиями, без ада обратного вызова. Вы можете написать код, который выглядит как боль старый процедурный код, но под ним есть магия, которая использует переключение задач в пользовательском пространстве всякий раз, когда что-то блокируется. Звучит здорово. Проблема в том, что мы в конечном итоге решаем сложность с большей сложностью. swapcontext () и family довольно просты, сложность проистекает из других непреднамеренных мест.

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

Другая критика здесь :

У одного процесса, имитирующего несколько потоков, много проблем. Одним из них является то, что все поддельные темы останавливаются на любой странице ошибки.

Мой вопрос - являются ли go-lang goroutines (для пула по умолчанию) просто зелеными нитями? Если так - они обращаются к критике выше?

Hawkeye
источник

Ответы:

67

Я всего лишь случайный пользователь Go, поэтому возьмите с собой немного зерна.

Википедия определяет зеленые потоки как «потоки, которые планируются виртуальной машиной (ВМ), а не исходной операционной системой». Зеленые потоки эмулируют многопоточные среды, не полагаясь ни на какие собственные возможности ОС, и они управляются в пространстве пользователя, а не в пространстве ядра, что позволяет им работать в средах, в которых нет поддержки собственных потоков.

Go (точнее, две существующие реализации) - это язык, производящий только нативный код - он не использует виртуальную машину. Кроме того, планировщик в текущих реализациях среды выполнения опирается на потоки уровня ОС (даже когда GOMAXPROCS = 1). Поэтому я думаю, что говорить о зеленых нитях для модели Go немного оскорбительно.

Go люди придумали термин goroutine, особенно, чтобы избежать путаницы с другими механизмами параллелизма (такими как сопрограммы или потоки или легкие процессы).

Конечно, Go поддерживает модель потоков M: N, но она выглядит гораздо ближе к модели процесса Эрланга, чем к модели зеленых потоков Java.

Вот несколько преимуществ модели Go по сравнению с зелеными потоками (как реализовано в ранней версии JVM):

  • Можно эффективно использовать несколько ядер или процессоров прозрачным способом для разработчика. С Go разработчик должен позаботиться о параллелизме. Среда выполнения Go позаботится о параллелизме. Реализации зеленых потоков Java не масштабировались на несколько ядер или процессоров.

  • Системные вызовы и вызовы C не являются блокирующими для планировщика (все системные вызовы, а не только те, которые поддерживают мультиплексированные входы / выходы в циклах событий). Реализации зеленых потоков могут блокировать весь процесс, когда был выполнен системный вызов блокировки.

  • Копирование или сегментированные стеки. В Go нет необходимости указывать максимальный размер стека для программы. Стек увеличивается по мере необходимости. Одним из следствий этого является то, что для подпрограмм не требуется много памяти (4KB-8KB), поэтому огромное количество из них может быть успешно создано. Таким образом, использование Goroutine может быть повсеместным.

Теперь, чтобы обратиться к критике:

  • С Go вам не нужно писать планировщик пользовательского пространства: он уже снабжен средой выполнения. Это сложная часть программного обеспечения, но это проблема разработчиков Go, а не пользователей Go. Его использование прозрачно для пользователей Go. Среди разработчиков Go Дмитрий Вюков является экспертом в программировании без блокировок / без ожидания, и он, кажется, особенно заинтересован в решении возможных проблем производительности планировщика. Текущая реализация планировщика не идеальна, но она улучшится.

  • Синхронизация приносит проблемы с производительностью и сложность: это частично верно и для Go. Но обратите внимание, что модель Go пытается стимулировать использование каналов и чистую декомпозицию программы в параллельных процедурах, чтобы ограничить сложность синхронизации (т. Е. Обмен данными посредством обмена данными, а не разделение памяти для обмена данными). Кстати, эталонная реализация Go предоставляет ряд инструментов для решения проблем производительности и параллелизма, таких как профилировщик и детектор гонки .

  • Относительно ошибки страницы и «подделки нескольких потоков», пожалуйста, обратите внимание, что Go может запланировать выполнение программы для нескольких системных потоков. Когда один поток блокируется по какой-либо причине (сбой страницы, блокировка системных вызовов), это не мешает другим потокам продолжать планировать и запускать другие программы. Теперь верно, что сбой страницы заблокирует поток ОС, и все процедуры должны быть запланированы в этом потоке. Однако на практике память кучи Go не должна быть выгружена. Это было бы то же самое в Java: языки сборки мусора в любом случае не очень хорошо вмещаются в виртуальную память. Если ваша программа должна корректно обрабатывать ошибки страниц, если это возможно, потому что она должна управлять некоторой памятью вне кучи. В этом случае,

Таким образом, IMO, goroutines не являются зелеными нитями, и язык Go и текущая реализация в основном обращаются к этой критике.

Дидье Специя
источник
1
Отличный и подробный ответ на вопрос :)
Tuxdude
1
Мне нравится этот ответ, но есть ли у вас какие-либо ссылки на то, как / когда создаются потоки ОС?
Ларс
1
Один из самых больших недостатков Go Language - это создание потока ядра для каждого блокирующего системного вызова!
user1870400
8
Обратите внимание, что статья «зеленых нитей» в Википедии была изменена и теперь содержит «потоки, которые запланированы библиотекой времени выполнения или виртуальной машиной (ВМ)»; Это означает, что по этому определению ваш ответ больше не будет правильным, так как среда выполнения Go выполняет планирование / управление. Я думаю, что более полезно определять зеленые потоки как потоки пространства пользователя, контрастирующие с потоками ОС. И тогда, да, goroutines - зеленые нити наверняка.
mknecht
1
2-й, что @mknecht. Дело не в виртуальной машине, а во время выполнения. И Go определенно имеет время выполнения. (который управляет моделью потоков и сборкой мусора).
Тим Харпер