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 ответов

10 просмотров

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) имеется в виду?

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

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

кому не сложно распишите пожалуйста для какой цели тут вот эти скобки и в них пихается указатель?
Михаил Helper
15
Комрады, посоветуйте, куда копать? Стал прикручивать кастомизацию тем. В OnShow главной главной формы пытаюсь загрузить из файла настроек и применить тему (на скрине, как долж...
Ed Doc
13
Такс, блин, таки кто-то знает, каким образом работают макросы stdin/stdout/stderr? Я влез в stdio.h, там определения нет, отладил через асмокод - вызывается функция со странны...
The Bird of Hermes
18
я не магистр хаскеля, но разве не может лейзи тип конвертнуться в не-лейзи запросив вычисление содержимого прям при инициализации?
deadgnom32 λ madao
100
OnShow один раз вызывается? или возможен Hide?
Iluha Companets
14
Если у меня есть такой класс: Object = {} function Object:new(a_name, a_transform, a_color, a_mesh, a_material, a_shader, a_textures) local private = {} private.n...
Cuarno Vile
4
А еще в перле можно уже @arr1 + @arr2?
Sergei Zhmylove
53
Всем привет, на линуксе лучше на fasm или nasm учиться писать для начала ?
meszjol
14
@MrMiscipitlick А можешь макрос написать, который будет вычислять смещение относительно переданных меток? Просто .label1-.label2, и вернуть значение.
КТ315
35
зачем же переименовывать ? чтобы кол-во участников возросло или вдруг IBM от этого снова на свифте начнет кодить ? Я не понимаю что страшного в том что свифт гавно, если это т...
Oleh Nerzh
10
Карта сайта