programing tip

고 루틴은 어떻게 작동합니까?

itbloger 2021. 1. 8. 07:54
반응형

고 루틴은 어떻게 작동합니까? (또는 : 고 루틴과 OS 스레드 관계)


syscall을 호출하는 동안 다른 고 루틴이 어떻게 계속 실행될 수 있습니까? (GOMAXPROCS = 1을 사용할 때)
내가 아는 한 syscall을 호출 할 때 스레드는 syscall이 반환 될 때까지 제어를 포기합니다. Go는 블로킹 온 시스템 콜 고 루틴 당 시스템 스레드를 생성하지 않고 어떻게 이러한 동시성을 달성 할 수 있습니까?

로부터 문서 :

고 루틴

스레드, 코 루틴, 프로세스 등과 같은 기존 용어가 부정확 한 의미를 전달하기 때문에 고 루틴이라고합니다. 고 루틴에는 단순한 모델이 있습니다. 동일한 주소 공간에서 다른 고 루틴과 동시에 실행되는 함수입니다. 가볍고 스택 공간 할당보다 약간 비쌉니다. 스택은 작게 시작하므로 저렴하며 필요에 따라 힙 스토리지를 할당 (및 해제)하여 증가합니다.

고 루틴은 여러 OS 스레드에 멀티플렉싱되므로 I / O를 기다리는 동안 차단해야하는 경우 다른 스레드가 계속 실행됩니다. 그들의 디자인은 스레드 생성 및 관리의 많은 복잡성을 숨 깁니다.


고 루틴이 차단 된 경우 런타임은 차단중인 고 루틴이 차단을 중지 할 때까지 다른 고 루틴을 처리하기 위해 새 OS 스레드를 시작합니다.

참조 : https://groups.google.com/forum/#!topic/golang-nuts/2IdA34yR8gQ


좋습니다. 제가 배운 내용은 다음과 같습니다. 원시 시스템 호출을 수행 할 때 Go는 실제로 차단 고 루틴 당 스레드를 생성합니다. 예를 들어, 다음 코드를 고려하십시오.

package main

import (
        "fmt"
        "syscall"
)

func block(c chan bool) {
        fmt.Println("block() enter")
        buf := make([]byte, 1024)
        _, _ = syscall.Read(0, buf) // block on doing an unbuffered read on STDIN
        fmt.Println("block() exit")
        c <- true // main() we're done
}

func main() {
        c := make(chan bool)
        for i := 0; i < 1000; i++ {
                go block(c)
        }
        for i := 0; i < 1000; i++ {
                _ = <-c
        }
}

그것을 실행할 때 Ubuntu 12.04는 해당 프로세스에 대해 1004 스레드를보고했습니다.

반면에 Go의 HTTP 서버를 활용하고 1000 개의 소켓을 열면 운영 체제 스레드가 4 개만 생성되었습니다.

package main

import (
        "fmt"
        "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
}

func main() {
        http.HandleFunc("/", handler)
        http.ListenAndServe(":8080", nil)
}

따라서 차단 시스템 호출 당 IOLoop과 스레드가 혼합 된 것입니다.


할 수 없습니다. GOMAXPROCS = 1 일 때 한 고 루틴이 시스템 호출을 수행하든 다른 작업을 수행하든 한 번에 실행할 수있는 고 루틴은 1 개뿐입니다.

However, most blocking system calls, such as socket I/O, waiting for a timer are not blocked on a system call when performed from Go. They're multiplexed by the Go runtime onto epoll, kqueue or similar facilities the OS provides for multiplexing I/O.

For other kinds of blocking system calls that cannot be multiplexed with something like epoll, Go does spawn a new OS thread, regardless of the GOMAXPROCS setting (albeit that was the state in Go 1.1, I'm not sure if the situation is changed)


You have to differentiate processor number and thread number: you can have more threads than physical processors, so a multi-thread process can still execute on a single core processor.

As the documentation you quoted explain, a goroutine isn't a thread: it's merely a function executed in a thread that is dedicated a chunk of stack space. If your process have more than one thread, this function can be executed by either thread. So a goroutine that is blocking for a reason or another (syscall, I/O, synchronization) can be let in its thread while other routines can be executed by another.

ReferenceURL : https://stackoverflow.com/questions/24599645/how-do-goroutines-work-or-goroutines-and-os-threads-relation

반응형