잠시만 기다려 주세요

     '바다아이 사이트는 윤석열 정부 탄핵을 지지합니다.'
전체검색 :  
이번주 로또 및 연금번호 발생!!   |  HOME   |  여기는?   |  바다물때표   |  알림 (16)  |  여러가지 팁 (1056)  |  추천 및 재미 (151)  |  자료실 (22)  |  
시사, 이슈, 칼럼, 평론, 비평 (600)  |  끄적거림 (129)  |  문예 창작 (705)  |  바람 따라 (69)  |  시나리오 (760)  |  드라마 대본 (248)  |  
살인!


    golang

golang - golang 채널 channel, select, go 루틴 예제
이 름 : 바다아이   |   조회수 : 9176         짧은 주소 : https://www.bada-ie.com/su/?831591799905
서두에 가장 중요한 것 이야기 드립니다.
채널에 빈값이 오면 먹통 됩니다. 이 점은 생각하고 작업 하셔야 합니다.


채널(channel)은 두 고루틴이 서로 통신하고 실행흐름을 동기화하는 수단을 제공한다. 다음은 채널을 사용하는 예제 프로그램이다.

 
package main
 
import (
    "fmt"
    "time"
)
 
func pinger(c chan string) {
    for i := 0; ; i++ {
        c <- "ping"
    }
}
func printer(c chan string) {
    for {
        msg := <- c
        fmt.Println(msg)
        time.Sleep(time.Second * 1)
    }
}
func main() {
    var c chan string = make(chan string)
 
    go pinger(c)
    go printer(c)
 
    var input string
    fmt.Scanln(&input)
}


이 프로그램은 "ping"을 끊임없이 출력할 것이다(중단하려면 엔터 키를 친다). 
채널의 타입은 chan이라는 키워드 다음에 채널에 전달되는 것의 타입을 지정해서 나타낸다
(여기서는 문자열을 전달한다). <-(왼쪽 화살표) 연산자는 채널에 메시지를 전달하고 채널로부터 
메시지를 전달받는 데 사용한다. c <- "ping""ping"을 전달한다는 의미다. msg := <- c는 
메시지를 받아 그것을 msg에 저장한다는 의미다. fmt가 나오는 줄은 fmt.Println(<-c)라고도 작성할 수 있다. 
이 경우 앞의 줄을 제거해도 된다.
 

이 같은 식으로 채널을 이용하면 두 고루틴이 동기화된다. pinger가 메시지를 채널에 전송하려고 시도할 
경우 printer가 해당 메시지를 받을 준비가 될 때까지 대기할 것이다(이것은 블로킹으로 알려져 있다). 
이번에는 프로그램에 다른 전달자를 추가해서 무슨 일이 일어나는지 살펴보자. 다음 함수를 추가한다.
 
func ponger(c chan string) {
    for i := 0; ; i++ {
        c <- "pong"
    }
}


그리고 main 함수를 다음과 같이 수정한다.
 
func main() {
    var c chan string = make(chan string)
 
    go pinger(c)
    go ponger(c)
    go printer(c)
 
    var input string
    fmt.Scanln(&input)
}


이제 프로그램에서는 "ping""pong"이 번갈아 가면서 출력될 것이다.
 

채널 방향
 

채널 타입에 방향을 지정할 수 있는데, 그렇게 함으로써 채널이 보내거나 받기만 하도록 제한할 수 있다. 
예를 들어, pinger 함수의 서명을 다음과 같이 변경할 수 있다.
 
func pinger(c chan<- string)


이제 c는 보내기만 할 수 있다. c로부터 메시지를 받으려고 하면 컴파일 오류가 발생할 것이다. 
이와 비슷하게 출력기를 다음과 같이 변경할 수 있다.
 
func printer(c <-chan string)


이러한 제한이 없는 채널을 양방향 채널이라 한다. 양방향 채널은 전송 전용 채널이나 수신 전용 채널에 인자로 
받는 함수에 전달할 수 있지만 그 역은 성립하지 않는다.
 
Select
 

Go에는 switch와 비슷하게 동작하지만 채널에 대해서만 동작하는 select라는 특별한 구문이 있다.
 
func main() {
    c1 := make(chan string)
    c2 := make(chan string)
 
    go func() {
        for {
            c1 <- "from 1"
            time.Sleep(time.Second * 2)
        }
    }()
    go func() {
        for {
            c2 <- "from 2"
            time.Sleep(time.Second * 3)
        }
    }()
    go func() {
        for {
            select {
                case msg1 := <- c1:
                fmt.Println(msg1)
                case msg2 := <- c2:
                fmt.Println(msg2)
            }
        }
    }()
 
    var input string
    fmt.Scanln(&input)
}


이 프로그램은 "from 1"2초마다 출력하고 "from 2"3초마다 출력한다. select는 준비된 첫 번째 채널을 
골라 해당 채널로부터 메시지를 받는다(또는 해당 채널로 메시지를 보낸다). 하나 이상의 채널이 준비되면 
어느 채널로부터 메시지를 받을지 무작위로 선택한다. 준비된 채널이 없으면 사용 가능해질 때까지 문장 실행이 
차단된다.


select 구문은 제한 시간을 구현할 때 자주 사용된다.
 
select {
    case msg1 := <- c1:
        fmt.Println("Message 1", msg1)
    case msg2 := <- c2:
        fmt.Println("Message 2", msg2)
    case <- time.After(time.Second):
        fmt.Println("timeout")
}


time.After는 채널을 생성한 후 지정한 시간이 지나면 현재 시간을 해당 채널로 보낸다
(여기서는 현재 시간에 관심을 두지 않으므로 변수에 저장하지 않았다). 아울러 default 케이스를 지정할 수도 있다.
 
select {
    case msg1 := <- c1:
        fmt.Println("Message 1", msg1)
    case msg2 := <- c2:
        fmt.Println("Message 2", msg2)
    case <- time.After(time.Second):
        fmt.Println("timeout")
    default:
        fmt.Println("nothing ready")
}


default 케이스는 준비된 채널이 없을 경우 즉시 실행된다.

 
버퍼 채널
 

채널을 만들 때 make 함수에 두 번째 매개변수를 전달하는 것도 가능하다.
 
c := make(chan int, 1)


이렇게 하면 용량이 1인 버퍼 채널이 만들어진다. 보통 채널은 동기적으로 동작한다. 
즉, 채널의 양쪽이 다른 쪽이 준비될 때까지 기다린다. 버퍼 채널은 비동기적이다. 
즉, 메시지를 보내거나 받을 때 채널이 이미 꽉 차 있지 않는 이상 기다리지 않는다.



출처 : http://www.codingnuri.com/golang-book/10.html#section2
| |





      1 page / 6 page
번 호 카테고리 제 목 이름 조회수
179 golang golang , ... 바다아이 1712
178 golang golang , map . 바다아이 1324
177 golang Golang (, , data ) , ... 바다아이 1328
176 golang golang sort ... 바다아이 1558
175 golang golang html.EscapeString html.UnescapeString input value ... 바다아이 1685
174 golang golang go.mod go.sum . GOPATH SRC not module, 1.16 . 바다아이 4957
173 golang go 1.16 ... is not in GOROOT.. GOPATH .... . 바다아이 5843
172 golang , String Formatting 바다아이 7490
171 golang rand.Intn , random, , . 바다아이 6950
170 golang golang ... 바다아이 10027
169 golang golang gopath, goroot .. golang 바다아이 7612
168 golang golang ... Force download file example 바다아이 9411
167 golang golang , , cpu, memory, disk 바다아이 10700
166 golang golang , ... GOOS, GOARCH 바다아이 8482
165 golang golang checkbox ... 바다아이 8228
164 golang golang , , http .... 바다아이 8007
163 golang golang nil , nil , nil ... 바다아이 8351
162 golang 2 golang, go , .... golang .... 바다아이 11214
161 golang golang postgresql, mysql, mariadb ... ` Grave () .. .. 바다아이 8543
160 golang golang postgresql mysql, mariadb scan , null .. 바다아이 8681
159 golang golang , iconv 바다아이 11480
158 golang golang quote escape, unquote 바다아이 8882
157 golang golang , http errorLog , , ... 바다아이 8992
156 golang golang interface , 바다아이 8456
155 golang golang struct .... 바다아이 9128
154 golang golang map map , 바다아이 8660
153 golang golang map .... .... 바다아이 8178
152 golang golang slice copy 바다아이 8273
151 golang golang goto 바다아이 9127
150 golang golang slice sort , int, string, float64 바다아이 8605
| |









Copyright ⓒ 2001.12. bada-ie.com. All rights reserved.
이 사이트는 리눅스에서 firefox 기준으로 작성되었습니다. 기타 브라우저에서는 다르게 보일 수 있습니다.
[ Ubuntu + GoLang + PostgreSQL + Mariadb ]
서버위치 : 오라클 클라우드 춘천  실행시간 : 0.07876
to webmaster... gogo sea. gogo sea.