Golang

[Golang] 7. 동시성과 병렬성(고루틴, 채널)

comnic 2023. 12. 30. 10:15
반응형

7. 동시성과 병렬성

 

7.1 고루틴과 채널

고루틴(Goroutine):

  • Go 언어에서 제공하는 경량 스레드로, 비동기적인 동작을 구현하는 데 사용됩니다.
  • 고루틴은 스레드보다 가벼우며, 많은 수의 고루틴을 생성하여 동시성을 구현할 수 있습니다.
package main

import (
	"fmt"
	"time"
)

func main() {
	// 고루틴 생성
	go printNumbers()
	go printLetters()

	// main 함수가 종료되는 것을 방지
	time.Sleep(2 * time.Second)
}

func printNumbers() {
	for i := 1; i <= 5; i++ {
		fmt.Println("Number:", i)
		time.Sleep(100 * time.Millisecond)
	}
}

func printLetters() {
	for char := 'A'; char <= 'E'; char++ {
		fmt.Println("Letter:", string(char))
		time.Sleep(100 * time.Millisecond)
	}
}

 

채널(Channel):

  • 고루틴 간에 안전하게 데이터를 주고받을 수 있는 통로입니다.
  • 채널은 make 함수를 사용하여 생성되며, <- 연산자로 데이터를 보내거나 받습니다.
package main

import (
	"fmt"
	"time"
)

func main() {
	// 문자열을 전달하는 채널 생성
	messageChannel := make(chan string)

	// 고루틴 시작
	go sendMessage(messageChannel)

	// 채널을 통해 메시지 수신
	message := <-messageChannel
	fmt.Println("Received message:", message)
}

func sendMessage(ch chan string) {
	// 채널을 통해 메시지 전송
	ch <- "Hello, Channel!"

	// 메시지 전송 후 대기
	time.Sleep(2 * time.Second)
}

 

병렬성(Parallelism):

  • 물리적으로 별개의 실행 단위(스레드, 프로세스 등)가 동시에 실행되는 것을 의미합니다.
  • 여러 작업이 동시에 진행되어 전체 시스템 성능을 향상시킬 수 있습니다.

동시성(Concurrency):

  • 논리적으로 여러 작업이 동시에 진행되는 것을 의미합니다.
  • 싱글 스레드에서 여러 작업을 동시에 처리하거나, 병렬 실행 단위가 없는 환경에서도 구현될 수 있습니다.
  • 동시성은 병렬성을 달성하기 위한 하나의 방법입니다.

 

7.2 동시성을 지원하는 패턴 소개

Select 문:

  • 여러 채널 간에 비동기적으로 통신할 때 사용됩니다.
  • 여러 채널 중에서 먼저 수신 가능한 채널의 동작을 수행합니다.
package main

import (
	"fmt"
	"time"
)

func main() {
	ch1 := make(chan string)
	ch2 := make(chan string)

	go func() {
		time.Sleep(2 * time.Second)
		ch1 <- "Message from Channel 1"
	}()

	go func() {
		time.Sleep(1 * time.Second)
		ch2 <- "Message from Channel 2"
	}()

	// Select 문을 통한 동시성 처리
	select {
	case msg1 := <-ch1:
		fmt.Println(msg1)
	case msg2 := <-ch2:
		fmt.Println(msg2)
	}
}

 

컨텍스트(Context):

  • 동시성 작업을 관리하고 중단할 수 있는 기능을 제공합니다.
  • 타임아웃, 취소, 데드라인 등을 설정하여 동작을 제어할 수 있습니다.
package main

import (
	"context"
	"fmt"
	"time"
)

func main() {
	// 1초 타임아웃 설정
	ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
	defer cancel()

	select {
	case <-time.After(2 * time.Second):
		fmt.Println("Operation completed successfully.")
	case <-ctx.Done():
		fmt.Println("Operation timed out.")
	}
}

이러한 패턴들을 사용하여 동시성 작업을 효과적으로 관리하고, 여러 작업이 안전하게 진행될 수 있도록 구현할 수 있습니다.

반응형