>  기사  >  백엔드 개발  >  Go에서 고루틴을 어떻게 사용하나요?

Go에서 고루틴을 어떻게 사용하나요?

WBOY
WBOY원래의
2023-05-11 15:39:061145검색

Go 언어는 동시성을 지원하는 프로그래밍 언어이며, 핵심 기능 중 하나는 고루틴입니다. 고루틴은 프로그램에서 동시 실행 프로세스를 생성할 수 있게 해주는 경량 스레드입니다. 고루틴을 사용하면 효율적인 동시 프로그램을 쉽게 작성할 수 있습니다. 이번 글에서는 Go에서 고루틴을 사용하는 방법을 배워보겠습니다.

고루틴이란 무엇인가요?

고루틴은 Go 런타임에서 관리하는 경량 스레드입니다. 운영 체제 스레드와 달리 고루틴은 운영 체제 커널에 의해 관리되지 않지만 Go 런타임에 의해 지원됩니다. 따라서 고루틴은 더 가볍고, 고루틴을 생성하고 파괴하는 것이 운영 체제 스레드보다 빠릅니다. 고루틴은 Go 언어 동시성의 핵심으로, 함수 본문을 동시에 분리하고 실행할 수 있는 기능을 지원합니다.

고루틴 생성 방법

Go에서는 go 키워드를 사용하여 새 고루틴을 생성할 수 있습니다. 다음은 간단한 예입니다: go来创建一个新的Goroutine。下面是一个简单的例子:

package main

import (
    "fmt"
    "time"
)

func hello() {
    fmt.Println("Hello goroutine!")
}

func main() {
    go hello()
    time.Sleep(1 * time.Second)
    fmt.Println("main function")
}

在这个例子中,我们定义了一个hello函数,它会在一个新的Goroutine中执行。我们在main函数中使用关键字go创建一个新的Goroutine,将hello函数作为参数传递给它。当我们运行程序时,hello函数将在一个新的Goroutine中异步运行,而main函数则会继续执行。我们使用time.Sleep函数让main函数等待1秒钟,以确保hello函数有足够的时间执行。

Goroutines的执行流程

创建Goroutines后,它会和主线程并发执行,Goroutines可以异步地并发执行其他的函数或代码。Go程序会在一个主Goroutine中启动。当我们使用关键字go创建一个新的Goroutine时,Go runtime会创建一个新的轻量级线程并分配一个Goroutine栈,然后将该Goroutine添加到Go runtime的调度器中。Go runtime会根据调度算法去选择一个可用的Goroutine运行,这些可用Goroutines中可能会有其他Go程序中的Goroutine。如果Go runtime没有发现有可用的Goroutine,那么程序可能会进入休眠状态。

Goroutines的调度

Go runtime使用Go scheduler调度器来调度Goroutines的运行。当我们创建一个新的Goroutine时,它会被添加到调度器的运行队列中。当调度器准备运行Goroutine时,它会从队列中选择一个Goroutine运行,直到该Goroutine阻塞或调用了time.Sleep等函数。在这种情况下,调度器会暂停该Goroutine的执行,并将它放回到队列中,直到它再次准备好运行。

Goroutines的阻塞

阻塞是指Goroutines无法继续执行的情况。当Goroutine调用了某些会引起阻塞的函数时,该Goroutine会被暂停,直到函数返回结果。这些函数包括:I/O操作,网络请求,系统调用,锁等。如果Goroutine处于阻塞状态,调度器会将该Goroutine放回到队列中,直到它再次准备好运行。

Goroutines的同步

在Go中,我们可以使用通道(Channel)来进行Goroutines之间的同步和通信。通道是一种用于在Goroutines之间传递数据的机制,它可以阻塞Goroutines的运行。以下是一个使用通道进行同步的例子:

package main

import (
    "fmt"
)

func main() {
    ch := make(chan int)

    go func() {
        fmt.Println("Goroutine starts")
        ch <- 1
    }()

    fmt.Println("Main goroutine waiting")
    <-ch
    fmt.Println("Main goroutine exiting")
}

在这个例子中,我们首先创建了一个通道ch,然后在一个新的Goroutine中执行一个函数。在函数中,我们打印了一条消息,并将数字1写入通道。在main函数中,我们在通道上等待,直到我们收到了一个值。一旦我们收到了值,main函数将退出。这是一个非常简单的例子,但它演示了如何使用通道在Goroutines之间进行同步。

Goroutines的错误处理

当Goroutine出现错误时,它会崩溃,并抛出一个Panic错误。在一个Goroutine发生错误时,它的错误信息只会被输出到控制台,并且无法访问Goroutine的状态。为了避免程序崩溃,我们可以使用recover函数来恢复Panic错误。以下是一个使用recover函数的例子:

package main

import (
    "fmt"
)

func main() {
    // define a function to run inside Goroutine
    goroutineFunc := func() {
        defer func() {
            if err := recover(); err != nil {
                fmt.Println("Error:", err)
            }
        }()
        fmt.Println("Goroutine started")
        panic("Something went wrong")
    }

    // start Goroutine
    go goroutineFunc()

    // wait in case Goroutine is not finished yet
    var input string
    fmt.Scanln(&input)
    fmt.Println("End of program")
}

在这个例子中,我们首先定义了一个函数goroutineFunc,它会在一个新的Goroutine中执行。在函数中,我们打印了一条消息,并调用了panic函数来模拟一个错误。在goroutineFunc中,我们使用defer关键字来定义一个函数,该函数用于捕获Panic错误。当我们在goroutineFunc中执行panic函数时,它会崩溃并抛出一个Panic错误。由于我们在defer函数中使用了recoverrrreee

이 예에서는 새 고루틴에서 실행될 hello 함수를 정의합니다. main 함수에서 키워드 go를 사용하여 새 고루틴을 만들고 hello 함수를 매개변수로 전달합니다. 프로그램을 실행하면 hello 함수는 새 고루틴에서 비동기적으로 실행되고 main 함수는 계속 실행됩니다. hello 함수가 실행될 충분한 시간을 갖도록 time.Sleep 함수를 사용하여 main 함수가 1초 동안 기다리도록 합니다.

고루틴 실행 프로세스🎜🎜고루틴을 생성한 후에는 메인 스레드와 동시에 실행됩니다. 고루틴은 다른 기능이나 코드를 비동기식으로 동시에 실행할 수 있습니다. Go 프로그램은 기본 고루틴에서 시작됩니다. 새로운 고루틴을 생성하기 위해 go 키워드를 사용하면 Go 런타임은 새로운 경량 스레드를 생성하고 고루틴 스택을 할당한 다음 Go 런타임의 스케줄러에 고루틴을 추가합니다. Go 런타임은 스케줄링 알고리즘에 따라 실행할 수 있는 고루틴을 선택합니다. 이러한 사용 가능한 고루틴 중에서 다른 Go 프로그램에도 고루틴이 있을 수 있습니다. Go 런타임이 사용 가능한 고루틴을 찾지 못하면 프로그램은 절전 모드로 전환될 수 있습니다. 🎜🎜Scheduling of Goroutines🎜🎜Go 런타임은 Go 스케줄러 스케줄러를 사용하여 Goroutines 실행을 예약합니다. 새로운 고루틴을 생성하면 스케줄러의 실행 큐에 추가됩니다. 스케줄러가 고루틴을 실행할 준비가 되면 고루틴이 time.Sleep과 같은 함수를 차단하거나 호출할 때까지 실행할 대기열에서 고루틴을 선택합니다. 이 경우 스케줄러는 고루틴의 실행을 일시 중지하고 다시 실행할 준비가 될 때까지 이를 대기열에 다시 넣습니다. 🎜🎜Blocking of Goroutines🎜🎜Blocking은 고루틴이 계속 실행될 수 없는 상황을 의미합니다. 고루틴이 일부 차단 함수를 호출하면 함수가 결과를 반환할 때까지 고루틴이 일시 중지됩니다. 이러한 기능에는 I/O 작업, 네트워크 요청, 시스템 호출, 잠금 등이 포함됩니다. 고루틴이 차단되면 스케줄러는 다시 실행할 준비가 될 때까지 고루틴을 대기열에 다시 넣습니다. 🎜🎜고루틴 동기화🎜🎜Go에서는 채널을 사용하여 고루틴 간에 동기화하고 통신할 수 있습니다. 채널은 고루틴 간에 데이터를 전달하는 메커니즘으로, 고루틴의 실행을 차단할 수 있습니다. 다음은 동기화를 위해 채널을 사용하는 예입니다: 🎜rrreee🎜 이 예에서는 먼저 ch 채널을 만든 다음 새 고루틴에서 함수를 실행합니다. 함수에서 메시지를 인쇄하고 채널에 숫자 1을 썼습니다. main 함수에서는 값을 받을 때까지 채널에서 기다립니다. 값을 받으면 main 함수가 종료됩니다. 이것은 매우 간단한 예이지만 채널을 사용하여 고루틴 간에 동기화하는 방법을 보여줍니다. 🎜🎜고루틴에 대한 오류 처리🎜🎜고루틴에서 오류가 발생하면 충돌이 발생하고 패닉 오류가 발생합니다. 고루틴에서 오류가 발생하면 해당 오류 메시지는 콘솔에만 출력되며 고루틴의 상태에 접근할 수 없습니다. 프로그램 충돌을 방지하기 위해 복구 기능을 사용하여 패닉 오류를 복구할 수 있습니다. 다음은 복구 함수 사용 예입니다. 🎜rrreee🎜이 예에서는 먼저 새로운 고루틴에서 실행될 goroutineFunc 함수를 정의합니다. 함수에서는 메시지를 인쇄하고 panic 함수를 호출하여 오류를 시뮬레이션합니다. goroutineFunc에서는 defer 키워드를 사용하여 패닉 오류를 캡처하는 데 사용되는 함수를 정의합니다. goroutineFunc에서 panic 함수를 실행하면 충돌이 발생하고 Panic 오류가 발생합니다. defer 함수에서 recover 함수를 사용했기 때문에 이 오류를 캡처하고 콘솔에 오류 메시지를 출력할 수 있습니다. 🎜🎜결론🎜

고루틴은 Go 언어 동시성의 핵심 기능 중 하나이며 프로그램에서 병렬 실행 프로세스를 생성 및 처리하고 프로그램 성능을 향상시킬 수 있습니다. 이 글에서는 고루틴 생성 방법, 고루틴 실행 흐름, 스케줄링, 차단, 동기화 및 오류 처리 등을 포함하여 Go에서 고루틴을 사용하는 방법을 배웠습니다. 고루틴을 사용하면 효율적인 동시 프로그램을 쉽게 작성할 수 있습니다.

위 내용은 Go에서 고루틴을 어떻게 사용하나요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.