Подтвердить что ты не робот

В чем разница между многопоточным движением Go и потоками pthread или Java?

В чем разница между подходами многопоточности Go и другими подходами, такими как pthread, boost:: thread или Java Threads?

4b9b3361

Ответ 1

Цитата из Учебник 3-го дня < - прочитайте это для получения дополнительной информации.

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

Мы будем делать то же самое для CPU-bound goroutines в какой-то момент, но пока, если вы хотите, чтобы пользовательский уровень parallelism вы должен установить $GOMAXPROCS. или позвоните по телефону runtime.GOMAXPROCS(п).

Горотин не обязательно соответствует потоку ОС. Он может иметь меньший размер начального стека, и стек будет расти по мере необходимости.

Несколько gorouitines могут быть мультиплексированы в один поток, когда это необходимо.

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

Goroutines реализуется как pthreads в gccgo, поэтому он также может быть идентичен потоку ОС. Это отделяет концепцию потока ОС и наше мышление о многопоточности при программировании.

Ответ 2

В ссылочных компиляторах (5g/6g/8g) главный планировщик (src/pkg/runtime/proc.c) создает N потоков ОС, где N контролируется runtime.GOMAXPROCS(n) (по умолчанию 1). Каждый поток планировщика вытаскивает новую версию goroutine из главного списка и запускает ее. Горотин будет продолжать работать до тех пор, пока не будет сделан syscall (например, printf) или операция на канале, и в этот момент планировщик захватит следующий goroutine и запустит его с той точки, в которой он остановился (см. gosched() в src/pkg/runtime/chan.c).

Планирование для всех целей и целей реализовано с помощью сопрограмм. Та же функциональность может быть записана в прямом режиме C с использованием setjmp() и longjmp(), Go (и других языков, реализующих потоки с легким/зеленым потоком), просто автоматизирует процесс для вас.

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

Ответ 3

IMO, то, что делает многопоточность в Go привлекательным, - это средства связи: в отличие от pthread, где нужно построить инфраструктуру связи (мьютексы, очереди и т.д.), в Go он доступен по умолчанию в удобной форме.

Короче говоря, существует "низкое трение" для использования потоков из-за возможностей хорошего общения (сродни Erlang, если можно так сказать).

Ответ 4

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

Текущая реализация среды выполнения Go не будет распараллелить этот код по умолчанию. Он выделяет только одно ядро ​​для обработки пользовательского уровня. Произвольное количество goroutines может быть заблокировано в системных вызовах, но по умолчанию только один может выполнять код пользовательского уровня в любое время. Он должен быть умнее и в один прекрасный день будет умнее, но пока он не будет , если вы хотите CPU parallelism, вы должны указать время выполнения, сколько goroutines вы хотите выполнить код одновременно. Существует два способа сделать это. Либо запустите свою работу с переменной окружения GOMAXPROCS, установленной на количество ядер, чтобы использовать или импортировать пакет времени выполнения и вызвать runtime.GOMAXPROCS(NCPU). Полезным значением может быть runtime.NumCPU(), который сообщает количество логических процессоров на локальном компьютере. Опять же, ожидается, что это требование будет отменено по мере улучшения планирования и времени выполнения.

источник цитат

Пример программы, которая максимизирует мой процессор i5, - это (использует все 4 ядра при 100% в htop):

package main


import (
    "fmt"
    "time"
    "runtime"
)


func main() {
    runtime.GOMAXPROCS(4) // Set the maximum number of threads/processes

    d := make(chan string)
    go boring("boring!", d, 1)
    go boring("boring!", d, 2)
    go boring("boring!", d, 3)
    go boring("boring!", d, 4)

    for i := 0; i < 10; i++ {
        time.Sleep(time.Second);
    }

    fmt.Println("You're boring; I'm leaving.")
}

func boring(msg string, c chan string, id int) {
    for i := 0; ; i++ {

    }
}

Теперь это фактически ничего не делает, но посмотрите, как кратко/легко/просто сравнивается с написанием многопоточных приложений на других языках, таких как Java.