Если goroutines включают потоки пользовательского пространства, может ли операция блокировки привести к переключению контекста всего потока?


Прошу прощения, если этот вопрос слишком глуп. Я читал здесь подробности горотинов . Согласно этой странице, он говорит Goroutines are multiplexed onto a small number of OS threads, rather than a 1:1 mapping, что все, что я мог придумать с моими ограниченными знаниями, это ограниченное число потоков ОС, порожденных, внутри которых он может использовать потоки пространства пользователей или сопространства. Это правильно? И если это так, если я могу взять пример, если программа клонирует 4 потока ОС, внутри которых есть несколько потоков userspace, и есть один блокирующая операция внутри всех этих 4 потоков наряду с неблокирующими операциями будет ли контекст планировщика ОС переключать все эти потоки, поскольку потоки пространства пользователей не прозрачны для потоков ОС?

Из любопытства, есть ли возможная реализация c goroutines, которая могла бы помочь понять внутренности?

1 6

1 ответ:

Ниже то, что я понял после прочтения Перейти в действие

Goroutines работают в так называемых"логических процессорах" (не физических процессорах). Каждый из этих логических процессоров привязан к одному потоку ОС.

После Go 1.5 число логических процессоров равно числу доступных физических процессоров.

Планировщик Go разумно планирует запуск нескольких goroutines на каждом из этих логических процессоров

Грубая диаграмма следует :-

Операционной системы-нить ------ логический процессор ------ горутина 1, 2 горутина..... Goroutine n

Теперь очень вероятно, что один из Goroutines делает блокирующий системный вызов. Когда это происходит,

  1. Поток ОС и Goroutine, который сделал блокирующий вызов, являются отсоединен от логического процессора

    Этот логический процессор теперь не имеет потока ОС.

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

  3. Отсоединенный goroutine и поток ОС, с которым он связан, продолжают блокировать, ожидая возвращения syscall.

  4. Когда системный вызов возвращается, функция goroutine повторно подключается к одному из логических процессоров и помещается в очередь выполнения.

  5. Поток ОС "отложен для дальнейшего использования". Я предполагаю, что это добавлено к какой-то нити бассейн.

Если goroutine выполняет вызов сетевого ввода-вывода, он обрабатывается несколько иным способом.

Функция goroutine отсоединяется от логического процессора и перемещается в интегрированный сетевой опросник. Как только опрашивающий говорит, что операция ввода-вывода готова, goroutine повторно подключается к логическому процессору для ее обработки.

-- Теперь, чтобы ответить на ваш вопрос: -)

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

Так как одна горутина на каждом из 4 потоков ОС сделала блокирующий syscall, все 4 потока будут отсоединены от своих логических процессоров и будут продолжать блокировать до тех пор, пока не вернутся syscall(ы). В 4-х нитка ОС будут связаны с соответствующими горутин, которые сделали блокирующий системный вызов.

Теперь это приводит к 4 логическим процессорам (и неблокирующим goroutines, присоединенным к ним) без каких-либо потоков ОС.

Итак, планировщик GO создает 4 новых потока ОС, и назначает логические процессоры этим потокам.

--

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

Таким образом, он будет переключать их контексты с каким-то другим неблокирующим потоком по своему выбору.