170 похожих чатов

Привет, чатик! А как гошка раскидывает работу по тредам ОС? Я думал,

что рантайм горутину отдаёт в тред и она там крутится. А оказывается, что одна часть горутины выполняется в одном треде ОС, а другая часть горутины в другом треде ОС.


Взять простой пример:

$ cat test.go
package main

import (
"net/http"
"fmt"
"time"
"strconv"
)

func main() {
time.Sleep(2 * time.Second)
fmt.Println("let's go!")
for i:=0; i<20; i++{
fname := "func"+strconv.Itoa(i)
go doJob(fname)
}
time.Sleep(7 * time.Second)
}

func doJob(fname string) {
fmt.Println(fname)
resp, err := http.Get("http://ya.ru/")
fmt.Println(resp, err)
time.Sleep(5 * time.Second)
}

Стрейсим (до сих пор не пойму где ставить 2>&1, лол):

2>&1 strace -f go run test.go > /tmp/strace.goha 2>&1



А потом анализируем.


Сискол write() вызывался только в двух ОС тредах: 16502 и 16504:
$ grep write /tmp/strace.goha | grep func | cut -d' ' -f 2 | sort | uniq -c | sort -nrk1
19 16502]
1 16504]

При этом в потоке 16502 сокет открывался только 9 раз, что не совпадает с числом вызовов write() - 19:
$ grep 'socket(' /tmp/strace.goha | cut -d' ' -f 2 | sort | uniq -c | sort -nrk1
25 16506]
22 16509]
14 16505]
11 16508]
10 16510]
9 16504]
9 16502]

Какая тут логика?

17 ответов

14 просмотров

c go 1.14 планировщик у нас preemtible. Те неважно в какой стадии находится горутина - ее можно прервать и вызывать другую на том же треде Очень занимательный видос как это работает и как не получилось сделать https://www.youtube.com/watch?v=1I1WmeSjRSw

Elmanov Anton
c go 1.14 планировщик у нас preemtible. Те неважно...

причина зачем это сделано - сборщик мусора. он вынужден останавливать все треды периодически.

Andrey-Enshin Автор вопроса
Elmanov Anton
c go 1.14 планировщик у нас preemtible. Те неважно...

> Те неважно в какой стадии находится горутина - ее можно прервать и вызывать другую на том же треде Ну это вроде норм. А вот зачем горутину переносить в другой тред ОС? Я думаю, что рантайм дробить горутину на части и какие-то части отдаёт одному треду, а какие-то другому. Например, сетевые сисколы в один тредик, файловые - в другой. Об это как-то говорил @onokonem , но деталей не было. Спасибо за видос. Посмотрю

Andrey-Enshin Автор вопроса
Elmanov Anton
причина зачем это сделано - сборщик мусора. он вын...

кстати, он обязательно стопит все треды разом, типа стоп мир по всем фронтам или таки может почистить сначала один тредик ОС, потом другой?

Elmanov Anton
c go 1.14 планировщик у нас preemtible. Те неважно...

Это не совсем так. Вытеснение используется только как fallback

Andrey Enshin
> Те неважно в какой стадии находится горутина - е...

> А вот зачем горутину переносить в другой тред ОС? потому что треды это воркер пул, который выполняет горутины. и порядок там сложно предсказать. как раз таки ассоциировать рутину с тредом было сложнее, имхо

Andrey Enshin
кстати, он обязательно стопит все треды разом, тип...

стопит все разом но на 2 коротких этапа - доли микросекунд. между ними работает конкурретно и без блокировок.

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

Daniel Podolsky
Это не совсем так. Вытеснение используется только ...

в видосе что выше скинул, про вытеснение говорят как про основной метод остановки рутин для переключения. видос 20го года про го 1.14 - должно быть актуально. можете кинуть ссылок в уточняющий источник плз

Daniel Podolsky
если горутине надо поспать, например, в ожидании с...

именно отправляет или помечает, что горутину можно выполнить?

c
а в чем разница?

ну, сразу к треду привязать или возможно сразу выполним, а может потом

Elmanov Anton
в видосе что выше скинул, про вытеснение говорят к...

я видос смотреть сейчас не буду, поэтому и спорить с ним не стану.

Daniel Podolsky
я видос смотреть сейчас не буду, поэтому и спорить...

там микс подходов с GC, но якобы OS signals основной и единственный способ остановки.

Alexey Ermakov
ну, сразу к треду привязать или возможно сразу вып...

там есть глобальная и локальная очередь, и, если мне не изменяет память, шедулер после I/O помещает в локальную

c
там есть глобальная и локальная очередь, и, если м...

локальная это локальная для P (m-p-g) имеется в виду?

Похожие вопросы

Обсуждают сегодня

А как старый хаскел с новым стыковать ? потому как тут работает https://play.haskell.org/saved/C3xpMzcd, а вот тут https://stepik.org/lesson/7602/step/9?unit=1473 нет ошибка C...
Fedor
131
что насчет пагинга? на осдеве непонятно(
Vi Chapmann 🪙
26
Вопрос я правильно понимаю что в коде newtype ArrowMap k v = ArrowMap { getArrowMap :: k -> Maybe v } getArrowMap есть функция типа k -> Maybe v, если да, то не понимаю задач...
Fedor
64
Ребят, что лучше для реверса: гидра или ида?
En Vind Av Sorg
26
Делаю велосипед логгер. К сообщению хочу прикрутить некоторую информацию, типа, кем отправлено, какой уровень, и всякое такое. И тут подумалось мне, почему бы не хранить весь...
Serjone
24
Как Вы считаете нормально ли в двадцатых годах 21 века в ВУЗах Российской Федерации обучать студентов работе с TASM? Не слишком ли это "архаично"? (Если оффтоп или флейм для э...
Spiker01
52
Комрады, хотел уточнить. Проперть в OnDestroy юнита-хозяина по-прежнему доступна? И еще уточнение: finalization юнита наступает раньше или позже OnDestroy?
Ed Doc
48
если загрузчик efi? если сама PML4 PDPT PDT PT лежит в неудобном для меня месте?
Vi Chapmann 🪙
8
Продолжая диалог про свифт в проде – сейчас возник вопрос в активном наборе бекендеров. В основном в нашей компании мы фанаты Java Spring и полностью ей довольны. Однако найм ...
Guseyn
27
Читаю сейчас [нет, уже больше не читаю!] курсовую о Булгакове, написанную, похоже, с помощью ChatGPT. Это удивительный психоделический опыт. Текст в основном написан в стиле б...
✨ Uni [🌊 В отпуске]
1
Карта сайта