Если goroutines включают потоки пользовательского пространства, может ли операция блокировки привести к переключению контекста всего потока?
Прошу прощения, если этот вопрос слишком глуп. Я читал здесь подробности горотинов . Согласно этой странице, он говорит Goroutines are multiplexed onto a small number of OS threads, rather than a 1:1 mapping
, что все, что я мог придумать с моими ограниченными знаниями, это ограниченное число потоков ОС, порожденных, внутри которых он может использовать потоки пространства пользователей или сопространства. Это правильно? И если это так, если я могу взять пример, если программа клонирует 4 потока ОС, внутри которых есть несколько потоков userspace, и есть один блокирующая операция внутри всех этих 4 потоков наряду с неблокирующими операциями будет ли контекст планировщика ОС переключать все эти потоки, поскольку потоки пространства пользователей не прозрачны для потоков ОС?
Из любопытства, есть ли возможная реализация c goroutines, которая могла бы помочь понять внутренности?
1 ответ:
Ниже то, что я понял после прочтения Перейти в действие
Goroutines работают в так называемых"логических процессорах" (не физических процессорах). Каждый из этих логических процессоров привязан к одному потоку ОС.
После Go 1.5 число логических процессоров равно числу доступных физических процессоров.
Планировщик Go разумно планирует запуск нескольких goroutines на каждом из этих логических процессоров
Грубая диаграмма следует :-
Операционной системы-нить ------ логический процессор ------ горутина 1, 2 горутина..... Goroutine n
Теперь очень вероятно, что один из Goroutines делает блокирующий системный вызов. Когда это происходит,
Поток ОС и Goroutine, который сделал блокирующий вызов, являются отсоединен от логического процессора
Этот логический процессор теперь не имеет потока ОС.
Планировщик Go создает новый поток ОС и присоединяет его к логическому процессору. Остальные горотины, которые были присоединены к логическому процессору, теперь продолжают работать.
Отсоединенный goroutine и поток ОС, с которым он связан, продолжают блокировать, ожидая возвращения syscall.
Когда системный вызов возвращается, функция goroutine повторно подключается к одному из логических процессоров и помещается в очередь выполнения.
Поток ОС "отложен для дальнейшего использования". Я предполагаю, что это добавлено к какой-то нити бассейн.
Если goroutine выполняет вызов сетевого ввода-вывода, он обрабатывается несколько иным способом.
Функция goroutine отсоединяется от логического процессора и перемещается в интегрированный сетевой опросник. Как только опрашивающий говорит, что операция ввода-вывода готова, goroutine повторно подключается к логическому процессору для ее обработки.
-- Теперь, чтобы ответить на ваш вопрос: -)
Я не эксперт, но это то, что я думаю произойдет, основываясь на том, что было заявлено выше.
Так как одна горутина на каждом из 4 потоков ОС сделала блокирующий syscall, все 4 потока будут отсоединены от своих логических процессоров и будут продолжать блокировать до тех пор, пока не вернутся syscall(ы). В 4-х нитка ОС будут связаны с соответствующими горутин, которые сделали блокирующий системный вызов.
Теперь это приводит к 4 логическим процессорам (и неблокирующим goroutines, присоединенным к ним) без каких-либо потоков ОС.
Итак, планировщик GO создает 4 новых потока ОС, и назначает логические процессоры этим потокам.
--
С точки зрения ОС, 4 потока ОС, которые сделали блокирующие вызовы, очевидно, не могут занимать процессорное время, так как они ничего не делают.
Таким образом, он будет переключать их контексты с каким-то другим неблокирующим потоком по своему выбору.