일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- mutex
- File
- 리뷰
- Sync
- Close
- package
- Linux
- install
- JavaScript
- C
- FOR
- 책
- window
- windows
- json
- range
- c++
- http
- tcp
- API
- Golang
- go언어
- bitcoin
- Callback
- write
- 영화
- Python
- go
- channel
- GO 언어
- Today
- Total
목록전체 글 (203)
Code Habit
C++ 개발을 하면서 여러 일을 동시에 처리해야 할때 멀티 쓰레드를 사용하여 처리한다. 이때 여러 쓰레드에서 동시에 일을 처리하기 위해 코어에서 쓰레드 사이를 옮겨다니며 컨텍스트 스위칭이 발생하는데 이는 자칫하면 부하를 일으켜 성능 저하를 유발하곤 한다. 하여 Go언어에서는 컨텍스트 스위칭 비용을 절약하기 위해 Go루틴이라는 Go 런타임에서 직접 관리하는 경량쓰레드를 제공한다. Go루틴은 명령을 수행하는 단일 흐름으로 OS 스레드를 이용하는 경량 스레드이다. Go언어는 CPU 코어, OS 스레드, 소루틴을 서로 조율하여 사용해 고루틴을 효율적으로 다룬다. 고루틴을 이용하면 코어와 스레드는 변경되지 않고 오직 고루틴만 옮겨 다니기 때문에 컨텍스트 스위칭이 일어나지 않는다. OS 스레드를 직접 사용하는 다른..
함수 리터럴은 이름 없는 함수로 함수명 없이 함수 타입 변숫값으로 대입되는 함숫값을 의미한다. 함수명이 없기 때문에 함수명으로 직접 함수를 호출할 수 없고 함수 타입 변수로만 호출된다. 이름이 없어 익명 함수라고도 한다. type opFunc func(a, b int) int func getOperator(op string) opFunc { if op == "+" { return func(a, b int) int { return a + b } } else if op == "*" { return func(a, b int) int { return a * b } } else { return nil } } func main() { fn := getOperator("*") result := fn(3, 4) // ..
함수 종료 전에 처리 해야 하는 코드가 있을 때 defer를 사용하면 된다. 파일핸들 반환 등에 사용하면 자칫 OS자원 사용 후 반환하지 않는 실수를 줄일 수 있다. func main() { f, err := os.Create("test.txt") if err != nil { fmt.Println("Failed to create file") return } defer fmt.Println("defer 1 !") defer fmt.Println("defer 2 !") defer f.Close() // main() 함수 종료 직전에 실행하여 파일 핸들 반환한다. defer fmt.Println("defer 3 !") } // 출력 순서 defer 3 ! // f.close() 실행 defer 2 ! defe..
fmt.Println()과 같이 함수 인수 개수가 고정적이지 않은 함수를 가변 인수 함수라고 한다. 가변 인수 함수는 '...' 키워드를 이용하여 만들 수 있다. func sum(args ...int) int { var sum = 0 for _, v := range args { sum += v } println("합계 : ", sum) return sum } func main() { sum(1, 2, 3, 4, 5, 6) } int형 가변 인수를 받는 함수 sum()을 정의하고 int형 변수들을 인수로 넘겨준다. 빈 인터페이스 interface{}를 이용하면 여러타입의 인수를 받을 수 있다. ( 모든 타입은 빈 인터페이스 interface{}를 포함한다.) func func1(args ...interfa..
for 반복문에서 range 키워드를 이용하여 배열/슬라이스 요소를 순회할 수 있다. func main() { var t []int = [5]int{1, 2, 3, 4, 5} for i, v = range t {// i : index( 0 ~ 4 ), v : value( 1 ~ 5 ) fmt.Println(i, v) } } for range 구문을 사용하여 채널에서 데이터를 계속 기다릴 수 있다. func main() { var wg sync.WaitGroup wg.Add(1) ch := make(chan int) go func() { defer wg.Done() for n := range ch { // ch에 값이 들어올때까지 대기, 채널을 닫으면 (close(ch)) for 구문을 빠져나온다. fmt..
중첩된 for문에서 break로 for문을 빠져 나오면 가장 가까운 for영역만 나오게 된다. 중첩된 for문을 완전히 빠져나오고 싶을때 label을 활용할 수 있다. func main() { a, b := 9, 9 Out: for i := 0; i < a; i++ { for j := 0; j < b; j++ { if j == 5 { break Out } } } } 'Out' 레이블을 최상단 for문 바로 위에 정의해주고 안쪽에서 break 할때 해당 레이블을 명시하면 중첩된 for문을 모두 빠져나온다. 참고로 레이블을 사용하여 중첩된 for문을 빠져나오는 것은 마치 goto문을 활용하는 것과 같기때문에 자칫 코드에 혼란을 가미할 수 있으니 꼭 필요한 경우만 사용하고 되도록 중첩된 for문의 사용을 지양..
bufio 패키지는 buffered I/O를 구현하며 io.Reader, io.Writer 객체를 래핑한다. bufio를 사용하면 버퍼를 활용해 I/O의 부하를 줄일 수 있다. bufio.NewReader 함수를 이용해 파일이나 표준입력스트림 등에서 defaultBufSize만큼 읽어올 수 있다. func NewReader(rd io.Reader) *Reader { return NewReaderSize(rd, defaultBufSize) } ex) func ReadFile(filename string) (string, error) { file, err := os.Open(filename) if err != nil { return "", err } defer file.Close() rd := bufio.N..
팝업 윈도우를 생성하고 직접 메시지를 이용해 윈도우 크기 변경하고 싶을 때 윈도우 메시지 WM_SYSCOMMAND, SC_SIZE를 활용할 수 있다. WM_LBUTTONDOWN 메시지 함수에서 다음과 같이 처리하면 된다. SendMessage(WM_SYSCOMMAND, SC_SIZE | HT_BOTTOMRIGHT); HT_BOTTOMRIGHT는 마우스 포인터가 해당 윈도우의 어디 부분에 위치해 있는지를 정해주는 값이므로 마우스 포인터가 위치하는 경계선 기준에 따라 아래와 같은 값들을 주면 된다. ( 위 예제 코드를 활용하여 실제 마우스 L버튼 클릭 후 드래그 하면 팝업 윈도의 오른하단 경계부분을 클릭 후 resize하는 것마냥 동작한다. ) #defineHT_NOWHERE0// On the screen ..