(Go : basic) 21. 채널 - 1

Posted by : at

Category : Go


package main

import (
	"fmt"
	"time"
)

func work1(v chan int) {
	fmt.Println("Work1 : S ---> ", time.Now())
	time.Sleep(1 * time.Second)
	fmt.Println("Work1 : E ---> ", time.Now())
	v <- 1
}

func work2(v chan int) {
	fmt.Println("Work2 : S ---> ", time.Now())
	time.Sleep(1 * time.Second)
	fmt.Println("Work2 : E ---> ", time.Now())
	v <- 2
}

func main() {
	//채널(Channel)
	//고루틴간의 상호 정보(데이터) 교환 및 실행 흐름 동기화 위해 사용 : 채널(동기식, 레퍼런스 타입)
	//실행 흐름 제어 가능(동기, 비동기) -> 일반 변수로 선언 후 사용 가능
	//데이터 전달 자료형 선언 후 사용(지정 된 타입만 주고받을 수 있음)
	//interface{} 전달을 통해서 자료형 상관없이 전송 및  수신가능
	//값을 전달(복사 후 : bool , int등) , 포인터(슬라이스, 맵) 등을 전달시에는 주의! -> 동기화 사용(Mutex)
	//멀티프로세싱 처리에서 교착상태(경쟁) 주의!
	// <- , ->  ( 채널 <- 데이터 : 송신) , ( <- 채널 : 수신)

	//예제1
	fmt.Println("Main : S ---> ", time.Now())

	//var v chan int
	//v = make(chan int)

	v := make(chan int) //int형 채널 선언
	go work1(v)
	go work2(v)

	<-v
	<-v
	fmt.Println("Main : E ---> ", time.Now())
}
package main

import (
	"fmt"
)

func rangeSum(rg int, c chan int) {
	sum := 0

	for i := 1; i <= rg; i++ {
		sum += i
	}
	c <- sum
}

func main() {
	//채널(Channel)

	c := make(chan int)

	go rangeSum(1000, c)
	go rangeSum(7000, c)
	go rangeSum(5000, c)

	//순서대로 데이터 수신(동기) : 채널에서 값 수신 완료 될 때까지 대기
	result1 := <-c
	result2 := <-c
	result3 := <-c

	fmt.Println("ex1 : ", result1)
	fmt.Println("ex1 : ", result2)
	fmt.Println("ex1 : ", result3)
}
$ ex1 :  500500
$ ex1 :  12502500
$ ex1 :  24503500
package main

import (
	"fmt"
	"time"
)

func main() {
	//채널(Channel)
	//예제1(동기 : 버퍼 미사용)

	ch := make(chan bool)
	cnt := 6

	go func() {
		for i := 0; i < cnt; i++ {
			ch <- true
			fmt.Println("Go : ", i)
			time.Sleep(1 * time.Second) //Sleep 주석 처리 후 테스트!
		}
	}()

	for i := 0; i < cnt; i++ {
		<-ch
		fmt.Println("Main : ", i)
	}
}
package main

import (
	"fmt"
	"runtime"
)

func main() {
	//채널(Channel)
	//예제1(비동기 : 버퍼 사용)
	//버퍼 : 발신 -> 가득차면 대기 , 비어있으면 작동 , 수신 -> 비어있으면 대기 , 가득차있으면 작동

	runtime.GOMAXPROCS(1)
	ch := make(chan bool, 4)
	cnt := 12

	go func() {
		for i := 0; i < cnt; i++ {
			ch <- true
			fmt.Println("Go : ", i)
		}
	}()

	for i := 0; i < cnt; i++ {
		<-ch
		fmt.Println("Main : ", i)
	}
}
package main

import (
	"fmt"
)

func main() {
	//채널(Channel
	//Close : 채널 닫기, 주의 -> 닫힌 채널에 값 전송 시 패닉(예외) 발생
	//Range : 채널안에서 값을 꺼낸다.(순회) , 채널 닫아야(Close) 반복문 종료 -> 채널이 열려 있고 값 전송하지 않으면 계속 대기!

	//예제1
	ch := make(chan bool)
	go func() {
		for i := 0; i < 5; i++ {
			ch <- true
		}
		close(ch) //5회 채널에 값 전송 후 채널 닫기
	}()

	for i := range ch { //채널에서 값을 꺼내온다.(채널이 Close 될 때까지)
		fmt.Println("ex1 : ", i)
	}
}
package main

import (
	"fmt"
)

func main() {
	//채널(Channel)
	//Close : 채널 닫기

	ch := make(chan int)

	go func() {
		for i := 0; i < 3; i++ {
			ch <- 77777
		}
	}()

	val1, ok1 := <-ch
	fmt.Println("ex1 : ", val1, ok1)
	val2, ok2 := <-ch
	fmt.Println("ex1 : ", val2, ok2)
	val3, ok3 := <-ch
	fmt.Println("ex1 : ", val3, ok3)

	close(ch) //채널 닫기
	val4, ok4 := <-ch
	fmt.Println("ex1 : ", val4, ok4)
}

About Taehyung Kim

안녕하세요? 8년차 현업 C++ 개발자 김태형이라고 합니다. 😁 C/C++을 사랑하며 다양한 사람과의 협업을 즐깁니다. ☕ 꾸준한 자기개발을 미덕이라 생각하며 노력중이며, 제가 얻은 지식을 홈페이지에 정리 중입니다. 좀 더 상세한 제 이력서 혹은 Private 프로젝트 접근 권한을 원하신다면 메일주세요. 😎

Star
Useful Links