괴발개발 성장기
반응형

Study/Go 언어 50

[golang] 고루틴 주의 사항

# 주의 사항 1) wg.Add(1) 위치가 중요하다 고루틴을 실행하기 전에 wg.Add(1) 를 실행야한다. waitGroup의 초기화를 로직 처리 전에 해줘야 타이밍 이슈를 피할 수 있다. 동시성 이슈가 있어서 add는 고루틴 실행 전에 한꺼번에 초기화를 해주는 것이 좋다. # 문제 발생 고루틴 안에서 add하고 done한다. func BadExWaitGroup() { fmt.Println("나쁜 예시 시작") size := 10 var wg sync.WaitGroup for i := 0; i < size; i++ { go func() { wg.Add(1) fmt.Printf("진행 중 %d \n", i) wg.Done() }() } wg.Wait() fmt.Println("나쁜 예시 끝") } 결과..

Study/Go 언어 2022.10.11

[golang] 고루틴이 끝나기 전에 main이 끝나는 문제 해결 방법

# 배경 고루틴이 끝나지도 않았는데 main 함수가 종료가 된다. # 해결방법 main은 고루틴이 끝났는지 알 수 없다. 그래서 WaitGroup 사용해야한다. # 예시 func Add() { sum := 1 + 2 fmt.Printf("합계 : %d \n", sum) } func GoroutineSolution() { fmt.Println("Goroutine 시작") var wg sync.WaitGroup wg.Add(1) go func() { Add() wg.Done() }() wg.Wait() fmt.Println("Goroutine 끝") } wg.Add(1) 해서 wg가 1이라고 생각하자. 고루틴이 다 끝나면 wg.Done()를 한다. 이건 -1이라고 생각하면 된다. wg.Wait() 는 0이 ..

Study/Go 언어 2022.10.10

[golang] 고루틴(goroutine) 기본 문법

# 고루틴이란? 경량화된 쓰레드(Thread) 일반적으로 OS 스레드 1개와 언어 쓰레드 1개를 사용한다. (1:1) 하지만 고언어는 OS 스레드 하나에 여러개의 고루틴을 사용한다. 즉 여러개의 스레드를 사용한다는 뜻이다. # 특징 메모리를 조금 사용한다. 그래서 성능이 더 좋다. 스레드를 바꾸는 것보다 컨텍스트(context) 스위칭이 더 빠르다. 고언어는 내부에 있는 Go 스케줄러 관리 해준다. 그래서 고루틴이 메모리를 적게 사용하다가 메모리가 더 필요하면 Go 스케줄러가 메모리를 더 할당해 준다. main도 고루틴이다. 고루틴은 메인과 함께 시작하고 끝난다. 메인 루틴이 종료되면 프로그램도 종료된다 Ex) 메인루틴, A고루틴, B고루틴 3개가 돌고 있는데 메인루틴이 종료되면 다른 고루틴들도 바로 종..

Study/Go 언어 2022.10.09

[golang] 채널(channel) blocking 해결 방법

2022.10.06 - [Study/Go 언어] - [golang] 채널(channel)에서 주의할 점 [golang] 채널(channel)에서 주의할 점 2022.10.05 - [Study/Go 언어] - [golang] 채널(channel) 기본 문법 [golang] 채널(channel) 기본 문법 # 채널이란? 값을 전달하는 통로이다. 고루틴에서 고루틴으로 서로 값을 주고 받을 때 많이 사용한다. # 채.. pink1016.tistory.com # 해결 방법 close를 해주면 된다. 값이 빠져나간 곳에 데이터 타입의 기본값이 들어간다. 예를 들어서 int는 0, string은 ""이 들어간다. ch := make(chan int, 3) ch

Study/Go 언어 2022.10.07

[golang] 채널(channel)에서 주의할 점

2022.10.05 - [Study/Go 언어] - [golang] 채널(channel) 기본 문법 [golang] 채널(channel) 기본 문법 # 채널이란? 값을 전달하는 통로이다. 고루틴에서 고루틴으로 서로 값을 주고 받을 때 많이 사용한다. # 채널 생성 방법 ch := make(chan 데이터타입, 사이즈) 예시 ch := make(chan int, 3) int 타입의 채널 pink1016.tistory.com # 주의할 점 1) 채널이 꽉 찼을 경우 예를 들어보자 ch := make(chan int, 3) ch

Study/Go 언어 2022.10.06

[Golang] XORM에서 this is incompatible with DISTINCT 에러 메시지 발생

# 배경 API를 돌리는데 에러 메시지가 떴다. # 에러 메시지 Error 3065: Expression #1 of ORDER BY clause is not in SELECT list, references column '테이블명.컬렁명' which is not in SELECT list; this is incompatible with DISTINCT # 해결방안 DISTINCT 사용하는 데 ORDER BY에 넣은 컬럼을 조회하지 않을 때 에러가 발생했다. 예를 들어서 builder := context.DB(c).Table(t.TableName()).Where("1=1").Desc("id").Select("distinct tag_id") 에러난 SQL문이다. 이 문장을 조회하는 tag_id로 order b..

Study/Go 언어 2022.09.23

[error] sql: expected 2 destination arguments in Scan, not 1 에러메시지 해결책

# 배경 XORM에 Get를 사용하는 과정에서 문제가 생겼다. SQL문을 체크 하는데도 데이터를 1개가 나왔다. 그런데 계속 에러메시지가 떴다. # 문제 sql: expected 2 destination arguments in Scan, not 1 # 코드 context.DB(c).Table(t.TableName()).Select("tag_id, updated").Where("del = 1"). And("tag_id= ?", tagID). Get(&tagID) # 원인 데이터 개수가 아니라 컬럼 수가 안맞아서 그런 것이다. 나는 select를 할 때 컬럼 2개를 찾는데 Get으로 받아오는건 id 하나 받는다고 해서 그랬다. # 해결책 1) Get(&tagID) 가 아니라 받을 컬럼을 구조체로 만들어서 컬..

Study/Go 언어 2022.08.04

[golang] jwt 토큰 생성 방법

golang에서 jwt 토큰 만들어 보자 # 생성 방법 1) 토큰에 넣을 정보를 구조체로 만들어보자 type UserClaim struct { Id string `json:"id"` Name string `json:"name"` Roles string `json:"roles"` } 2) 토큰을 넣을 구조체를 만들었다 => string으로 받아도 된다. 나는 나중에 RefreshToken도 만들 예정이어서 구조체로 만들었다. type JwtToken struct { AccessToken string } 3) json값을 map으로 전환해주는 함수 func (c UserClaim) ConvertMap() (map[string]interface{}, error) { bytes, err := json.Marsh..

Study/Go 언어 2022.07.08
반응형