Golang은 Google이 서버측 애플리케이션용으로 개발한 프로그래밍 언어입니다. 강력한 동시성 성능의 특성을 갖고 있어 분산 시스템 및 대규모 동시성 애플리케이션 개발에 점점 더 널리 사용되고 있습니다. 이 기사에서는 주로 Golang 언어의 동시성 구현을 소개합니다.
1. 동시성과 병렬성
Golang의 동시성 구현에 대해 이야기하기 전에 동시성과 병렬성의 두 가지 개념을 이해해야 합니다. 동시성은 동일한 프로그램 내에서 동시에 여러 작업을 수행할 수 있는 능력을 의미합니다. 병렬성이란 여러 작업을 동시에 수행하는 능력을 말합니다. 동시성을 구현하려면 스레드, 프로세스 및 운영 체제의 기타 메커니즘을 사용해야 하는 반면, 병렬성을 위해서는 멀티 코어 CPU와 같은 하드웨어 기능을 사용해야 합니다. 간단히 말해서 Golang의 동시성은 단일 스레드에서 구현되고 병렬성은 여러 스레드에서 구현됩니다.
2. Golang의 동시성 모델
Golang의 동시성 모델은 Goroutine과 Channel의 두 가지 개념을 기반으로 합니다. 고루틴은 코루틴을 기반으로 구현된 Golang에서 제공하는 경량 스레드입니다. 스레드에 비해 고루틴을 생성하고 파괴하는 오버헤드가 매우 적고, 고루틴 간 전환에 따른 오버헤드도 매우 적습니다. 따라서 많은 수의 고루틴을 열어 작업을 수행할 수 있어 애플리케이션의 동시성 성능이 향상됩니다.
고루틴만큼 중요한 것은 채널입니다. 채널은 Golang에서 제공하는 스레드로부터 안전한 통신 메커니즘입니다. 채널을 통해 고루틴은 실행을 전달하고 조정하여 데이터 공유 및 공동 작업을 달성하는 동시에 멀티 스레드가 동시에 발생할 수 있는 경쟁과 같은 문제를 피할 수 있습니다.
3. 고루틴 생성 및 호출 방법
고루틴은 go 키워드를 사용하여 생성 및 호출할 수 있습니다. 다음은 간단한 예입니다:
func main() { go func() { fmt.Println("This is a Goroutine!") }() fmt.Println("This is the main function!") time.Sleep(time.Second) }
위 예에서는 go 키워드를 사용하여 고루틴을 만들었습니다. 고루틴의 함수는 익명 함수를 사용하여 구현됩니다. "This is a Goroutine!"이라는 문자열을 출력하기 전에 프로그램은 먼저 "This is the main function!"이라는 문자열을 출력합니다. 고루틴은 비동기적으로 실행되기 때문에 애플리케이션은 고루틴 실행을 기다리지 않고 바로 종료됩니다. 고루틴이 실행될 시간을 가질 수 있도록 스레드가 일정 시간 동안 대기하도록 time 패키지의 Sleep 함수를 사용할 수 있습니다.
4. 채널 사용
Channel은 Golang에서 제공하는 스레드로부터 안전한 통신 메커니즘입니다. 여러 고루틴 간의 경쟁 문제를 방지하기 위해 고루틴 간에 정보를 동기화하고 데이터를 공유하는 데 사용할 수 있습니다.
채널 사용은 매우 간단합니다. 먼저 채널을 만들어야 합니다. 채널을 생성하려면 채널의 요소 유형을 지정해야 합니다. 다음은 채널 생성의 예입니다.
ch := make(chan int)
이 예에서는 make 함수를 사용하여 int 유형 요소로 채널을 생성합니다.
채널에 데이터를 보내려면 아래와 같이 채널의 전송 메서드(<- 연산자 사용)를 호출할 수 있습니다.
ch <- 10
이 예에서는 int 유형 데이터 10을 채널에 보냈습니다. 채널이 가득 차면 채널에 공간이 생길 때까지 작업이 차단됩니다.
채널에서 데이터를 수신하려면 아래와 같이 채널의 수신 메서드(<- 연산자 사용)를 호출할 수 있습니다.
n := <-ch
이 예에서는 채널에서 int 유형 데이터 n을 받았습니다. 채널이 비어 있으면 채널에 데이터가 있을 때까지 작업도 차단됩니다.
Channel에는 채널을 닫는 close 메서드, 채널의 요소 수를 가져오는 len 함수 등과 같은 다른 작업도 있습니다.
5. Golang 동시 프로그래밍 예제
아래에서는 Golang의 동시성 구현을 보여주기 위해 간단한 예제를 사용합니다.
배열에 있는 모든 요소의 평균을 계산해야 한다고 가정해 보겠습니다. 배열의 요소 수가 많기 때문에 계산에 시간이 많이 걸릴 수 있습니다. Golang의 동시성 메커니즘을 사용하여 계산 속도를 높일 수 있습니다.
먼저 int 유형의 요소 100개를 포함하는 배열 a를 정의합니다. 그런 다음 10개의 고루틴을 만들어 배열의 각 요소 값을 계산하고 마지막으로 모든 요소의 합계를 더한 다음 요소 수로 나누어 평균을 얻습니다.
func main() { a := make([]int, 100) for i := 0; i < len(a); i++ { a[i] = i } count := 10 resultChan := make(chan int, count) chunkSize := len(a) / count for i := 0; i < count; i++ { startIndex := i * chunkSize endIndex := (i + 1) * chunkSize if i == count-1 { endIndex = len(a) } go sumChunk(a[startIndex:endIndex], resultChan) } total := 0 for i := 0; i < count; i++ { total += <-resultChan } fmt.Println("Average value of array is: ", float32(total)/float32(len(a))) } func sumChunk(chunk []int, resultChan chan int) { sum := 0 for _, v := range chunk { sum += v } resultChan <- sum }
이 예에서는 길이가 100인 int 유형 배열 a를 정의합니다. 길이가 len(a)인 배열 a에 대해 배열 a에 있는 모든 요소의 합계를 계산하기 위해 개수(여기서는 10개)의 고루틴을 생성합니다. 각 고루틴은 배열 a의 하위 시퀀스의 합을 계산하고 그 결과를 resultChan으로 보냅니다. 마지막으로 resultChan에서 각 고루틴의 결과를 받아 이를 더해 모든 요소의 합계를 구하고 모든 요소의 평균을 계산합니다.
실제로 우리는 일반적으로 계산 요구 사항에 따라 고루틴 수를 설정합니다. CPU의 여러 코어를 활용할 수 있는 경우 고루틴 수를 CPU 코어 수로 설정할 수 있습니다. 그렇지 않으면 CPU 리소스를 합리적으로 사용하기 위해 필요에 따라 고루틴 수를 설정해야 합니다. 고루틴이 너무 많으면 시스템에 컨텍스트 전환 등의 문제가 발생하여 성능이 저하될 수 있습니다.
위 내용은 golang 언어의 동시성 구현의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!