[GoLang] 반복문에서 고루틴 돌릴 때 주의점

2024. 1. 19. 03:47· Go Lang/Study
목차
  1. 주의
  2. 왜 이런 일이
  3. 해결법

주의

반복문에서 고루틴을 돌리면 신기하게 결과물이 나올 때가 있습니다.

아래 코드를 실행했을 때의 결과는 무엇일까요?

import (
	"fmt"
	"sync"
)

func main() {
	var wg sync.WaitGroup
	for _, text := range []string{"a", "b", "c"} {
		wg.Add(1)
		go func() {
			defer wg.Done()
			fmt.Println(text)
		}()
	}
	wg.Wait()
}

 

만약 a, b, c가 랜덤으로 출력 것이라 생각하신다면 틀렸습니다

결과는 아래와 같습니다.

c
c
c

 

왜 이런 일이

이유는 루프문이 고루틴보다 먼저 끝나서 고루틴에서 사용할 수 있도록 메모리를 힙으로 옮겼기 때문입니다.

즉 for문이 먼저 끝나서 text의 값은 마지막 c를 가리키기에 이런 일이 발생한 것입니다.

 

참고로

※ 힙(Heap) : 동적으로 메모리를 할당한 부분, 사용자가 직접 할당 및 해제를 해야 함, 일반적으로 프로그램 실행 중의 생기고 제거됨

※ 스택(Stack) : 함수 내의 지역 변수 및 매개변수를 저장하며 LIFO으로 동작하며 해당 함수가 종료 시 제거함

해결법

해결법은 간단합니다, 고루틴이 실수로 할당이 해제되어야 하는 변수에 접근하지 못하도록 메모리에 값이 고정된 변수를 접근하게 수정하면 됩니다.

 

해당 기능은 이미 지원하고 있습니다.

아래 코드로 수정해 봅시다.

import (
	"fmt"
	"sync"
)

func main() {
	var wg sync.WaitGroup
	for _, text := range []string{"a", "b", "c"} {
		wg.Add(1)
        // 고루틴 함수에서 매개변수를 받도록 바꿈
		go func(text string) {
			defer wg.Done()
			fmt.Println(text)
		}(text)
	}
	wg.Wait()
}

위 코드처럼 간단하게 매개변수로 받게 수정함으로써 해결할 수 있습니다.

 

고루틴은 이것 외에도 주의해야 하는 점이 여러 개 있습니다.

아래는 동시성 환경에서 발생하는 문제점입니다, 보시고 도움이 되었으면 좋겠습니다.

 

https://seung.tistory.com/entry/GoLang-%EB%8D%B0%EB%93%9C%EB%9D%BD-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9D%BD-%EA%B8%B0%EC%95%84%EC%83%81%ED%83%9C-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-Deadlock-Livelock-Starvation?category=1161608

 

[GoLang] 데드락, 라이브락, 기아상태 이해하기 (Deadlock, Livelock, Starvation)

개요이번 포스팅은 Golang을 할 때 가장 큰 장점으로 꼽히는 부분인 동시성(고루틴)과 크게 관련된 내용입니다.동시성 프로그래밍은 사실 쉽지 않습니다.  동시에 실행된다는 개념 때문에 프로그

seung.tistory.com

 

 

위 글의 제목처럼 동시성 문제를 해결하기 위해서는 공유 메모리에 대해서

동기화된 접근만 하거나 고의 CSP( Communicating Sequential Processes ) 기본요소를 사용하면 됩니다.

  • Goroutine
  • Channel 
  • Select
  • Mutex
  • WaitGroup

 

반응형

'Go Lang > Study' 카테고리의 다른 글

[GoLang] GraphQL API 만들기 part 1 (라이브러리 탐색)  (38) 2024.03.01
[GoLang] GoLang 면접 질문 정리  (2) 2024.02.26
[GoLang] Go에서 동시성이란  (1) 2024.01.15
[GoLang] 데드락, 라이브락, 기아상태 이해하기 (Deadlock, Livelock, Starvation)  (1) 2024.01.02
[GoLang] Context가 뭘까요?  (2) 2023.12.02
  1. 주의
  2. 왜 이런 일이
  3. 해결법
'Go Lang/Study' 카테고리의 다른 글
  • [GoLang] GraphQL API 만들기 part 1 (라이브러리 탐색)
  • [GoLang] GoLang 면접 질문 정리
  • [GoLang] Go에서 동시성이란
  • [GoLang] 데드락, 라이브락, 기아상태 이해하기 (Deadlock, Livelock, Starvation)
DSeung
DSeung
DSeung
Dev log
DSeung
  • 분류 전체보기 (193)
    • PHP (62)
      • Laravel (31)
      • Error (5)
      • Setting (11)
      • Modern PHP (15)
    • Go Lang (51)
      • Study (30)
      • Algorithm (17)
      • Setting (1)
      • Error (3)
    • Java (11)
      • Spring (3)
      • JSP (0)
      • Error (2)
      • Setting (2)
      • 단축키 (2)
    • JavaScript (6)
      • Modern JavaScript (4)
      • Node (1)
    • Android Kotlin (5)
      • Study (4)
      • Error (1)
    • 컴퓨팅 기술 (12)
      • 데이터베이스시스템 (4)
      • Docker (2)
      • 크롤링 & 스크래핑 (1)
      • API (1)
      • 클라우드 (1)
      • 네트워크 (1)
    • MySQL (7)
    • AWS (1)
    • Git (5)
      • GItLab (1)
      • GitHub (4)
    • 도메인 (2)
      • 안과 (2)
    • 자격증 (7)
      • SQLD (1)
      • 정보처리기사 (6)
    • Mac os (1)
    • 나머지 (13)
      • tistory (1)
      • 기타 (9)
      • 일기 (3)
    • 독서 (10)

인기 글

최근 글

블로그 메뉴

  • 홈
  • 태그
전체
오늘
어제
hELLO · Designed By 정상우.v4.2.0
DSeung
[GoLang] 반복문에서 고루틴 돌릴 때 주의점
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.