golang에는 고루틴이라는 concurrency를 제공한다.


아래 예제는 한번에 동시에 실행하는 예제로서 클로져를 실행하는 코드이다.

 fmt.Scanln()은 입력을 기다리는 함수로서 고루틴이 모두 완료할 때까지 기다린다. 

package main

import (
"fmt"
"time"

)

func main() {
for i := 0; i <= 5; i++ {
go func() {
t := time.Now()
fmt.Println(t)
fmt.Println("Hello, World")
}()
}

fmt.Scanln()

}




결과는 다음과 같다.


2017-09-08 20:18:30.304976947 +0900 KST

Hello, World

2017-09-08 20:18:30.304985595 +0900 KST

Hello, World

2017-09-08 20:18:30.305044938 +0900 KST

Hello, World

2017-09-08 20:18:30.305051478 +0900 KST

Hello, World

2017-09-08 20:18:30.305007134 +0900 KST

Hello, World

2017-09-08 20:18:30.305108262 +0900 KST

Hello, World





runtime.GOMAXPROCS(n)은 프로세서를 얼마나 사용할지 cpu에 알린다.


package main

import (
"fmt"
"time"
"runtime"
)

func main() {
runtime.GOMAXPROCS(5)

//for i := 0; i <= 9000000 * 900000; i++ {
for i := 0; i <= 5; i++ {
go func() {
t := time.Now()
fmt.Println(t)
fmt.Println("Hello, World")
}()
}

fmt.Scanln()

}


cpu 모니터링을 해보면 확실히 알 수 있다.




모든 cpu를 활용하고 싶다면 runtime.NumCPU() 코드를 사용한다.

package main

import (
"fmt"
"time"
"runtime"
)

func main() {
fmt.Println(runtime.NumCPU())
runtime.GOMAXPROCS(runtime.NumCPU())

//for i := 0; i <= 9000000 * 900000; i++ {
for i := 0; i <= 5; i++ {
go func() {
t := time.Now()
fmt.Println(t)
fmt.Println("Hello, World")
}()
}

fmt.Scanln()

}



참고로 go 1.5부터는 rutnime.GOMAXPROCS()를 설정하지 않으면 모든 cpu를 사용하는 것이 디폴트이다.



다음은 channel 예제이다. channel은 go 루틴에서 사용되는 공용 변수이다. 

package main

import (
"fmt"
)

func multifly(value int, ch chan int) {
ch <- value * value
}

func main() {
channel := make(chan int)
go multifly(10, channel)
result := <-channel
fmt.Println(result)
}

채널(channel)을 생성하고 가지고 논 다음, 채널(channel) 값을 일반 변수에 저장한다. 



결과 값은 100이다.



참고로 multifly를 호출할 때 go를 사용하지 않으면 deadlock 에러가 발생한다.


fatal error: all goroutines are asleep - deadlock!



채널은

channel <- 값 : channel에 값 저장
x: <- channel : 채널에 값이 저장될 때까지 기다리고 x에 값을 할당한다. 



하지만 channel 값을 할당하지 않고 대기하는 의미로 쓰일 수도 있다. (예, 시그널)

package main


func multifly(value int, ch chan int) {
ch <- value * value
}

func main() {
channel := make(chan int)
go multifly(10, channel)
<-channel
}




채널에 2개의 버퍼를 사용하고 싶다면 다음과 같이 사용한다. 

buffer := make(chan bool, 2)



운영 체제 시그널을 고루틴으로 처리할 수 있다. 


package main

import (
"fmt"
"os/signal"
"os"
"syscall"
)

func main() {
sigs := make(chan os.Signal, 1)
done := make(chan bool, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
go func() {
sig := <-sigs
fmt.Println()
fmt.Println(sig)
done <- true
}()

fmt.Println("awaiting signal")
<-done
fmt.Println("exiting")
}


실행결과는 다음과 같다. 중간에 Ctrl+C(SIGINT)를 보내야 종료된다.



$ go run Test.go

awaiting signal

^D

^E

^C

interrupt

exiting

'golang' 카테고리의 다른 글

ts2dt 타임스탬프를 날짜로 변경해주기  (0) 2019.10.11
go 언어의 gc 소개 자료.  (0) 2018.07.19
[golang] 매개 변수 받기  (0) 2017.09.08
[golang] 에러(error) 예제  (0) 2017.09.07
[golang] defer 예제  (0) 2017.09.07
Posted by '김용환'
,



ssh tunning을 통해 내부 망에서 외부 망으로 연결할 수 있다. 관련 예제를 소개한다.



A 서버에서 B 서버를 통해 외부 망으로 접근할 수 있도록 터널링하는 예제이다. -v는 내부 구조를 알기 위해..



$ ssh -v -L 61514:rsync.apache.org:873 deploy@tunnel.interal.google.io  -i /root/.ssh/repo

 

 OpenSSH_6.6.1, OpenSSL 1.0.1f 6 Jan 2014

debug1: Reading configuration data /root/.ssh/config

debug1: Reading configuration data /etc/ssh/ssh_config

debug1: /etc/ssh/ssh_config line 19: Applying options for *

debug1: Connecting to tunnel.interal.google.io [1.1.1.1] port 22.

debug1: Connection established.

debug1: permanently_set_uid: 0/0

debug1: identity file /root/.ssh/repo type -1

debug1: identity file /root/.ssh/repo-cert type -1

debug1: Enabling compatibility mode for protocol 2.0

debug1: Local version string SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.8

debug1: Remote protocol version 2.0, remote software version OpenSSH_7.2p2 Ubuntu-4ubuntu2.2

debug1: match: OpenSSH_7.2p2 Ubuntu-4ubuntu2.2 pat OpenSSH* compat 0x04000000

debug1: SSH2_MSG_KEXINIT sent

debug1: SSH2_MSG_KEXINIT received

debug1: kex: server->client aes128-ctr hmac-sha1-etm@openssh.com none

debug1: kex: client->server aes128-ctr hmac-sha1-etm@openssh.com none

debug1: sending SSH2_MSG_KEX_ECDH_INIT

debug1: expecting SSH2_MSG_KEX_ECDH_REPLY

debug1: Server host key: ECDSA

debug1: Host 'tunnel.interal.google.io' is known and matches the ECDSA host key.

debug1: Found key in /root/.ssh/known_hosts:19

debug1: ssh_ecdsa_verify: signature correct

debug1: SSH2_MSG_NEWKEYS sent

debug1: expecting SSH2_MSG_NEWKEYS

debug1: SSH2_MSG_NEWKEYS received

debug1: SSH2_MSG_SERVICE_REQUEST sent

debug1: SSH2_MSG_SERVICE_ACCEPT received

debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password

debug1: Next authentication method: gssapi-keyex

debug1: No valid Key exchange context

debug1: Next authentication method: gssapi-with-mic

debug1: Next authentication method: publickey

debug1: Trying private key: /root/.ssh/tunnel

debug1: key_parse_private2: missing begin marker

debug1: read PEM private key done: type RSA

debug1: Authentication succeeded (publickey).

Authenticated to tunnel.interal.google.io ([1.1.1.1]:22).

debug1: Local connections to LOCALHOST:61514 forwarded to remote address rsync.apache.org:873

debug1: Local forwarding listening on 127.0.0.1 port 61514.

debug1: channel 0: new [port listener]

debug1: Local forwarding listening on ::1 port 61514.

bind: Cannot assign requested address

debug1: channel 1: new [client-session]

debug1: Requesting no-more-sessions@openssh.com

debug1: Entering interactive session.

debug1: client_input_global_request: rtype hostkeys-00@openssh.com want_reply 0

debug1: Sending environment.

debug1: Sending env LANG = en_US.UTF-8

Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-93-generic x86_64)


 * Documentation:  https://help.ubuntu.com

 * Management:     https://landscape.canonical.com

 * Support:        https://ubuntu.com/advantage

Last login: Thu Sep  7 23:49:54 2017



ps -ef로 보면 연결이 잘 되었다는 것을 확인할 수 있다. 


실제 소켓 단에서도 잘 연결되었는지 확인하려면 A 서버, B 서버에서 소켓을 확인한다.



A 서버에서 확인하기


$ netstat -anp

tcp        0      0 1.1.1.1:22      3.3.3.3:61518    ESTABLISHED -





B 서버에서 확인하기   


$ netstat -tpln

(No info could be read for "-p": geteuid()=1000 but you should be root.)

Active Internet connections (only servers)

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name

tcp        0      0 127.0.0.1:61514         0.0.0.0:*               LISTEN      -




Posted by '김용환'
,


go언어에서 매개 변수를 받을 수 있다. 기본 값을 


package main

import (
"fmt"
"flag"
)

func main() {
id := flag.String("id", "iiiii", "aaaaa")
name := flag.String("name", "nnnnn", "bbbbb")

flag.Parse()
fmt.Println("id:", *id)
fmt.Println("name:", *name)
fmt.Printf("%v %v\n", *id, *name)
}



결과는 다음과 같다. 디폴트값을 넣은 효과가 발휘된다.


$ ./Test -id=1 -name=samuel

id: 1

name: samuel

1 samuel


$ ./Test  -name=samuel

id: iiiii

name: samuel

iiiii samuel



$./Test -id=1

id: 1

name: nnnnn

1 nnnnn




flag.PrintDefaults()와 flag.Args(), flag.Arg(i)에 대한 쓰임을 살펴본다. 


원하는 매개 변수가 정해지지 않았다면 flag.PrintDefaults()를 통해 flag.String()에서 정의된 내용이 나타나고,


flag.Args()는 주어진 매개 변수외 추가로 매개 변수가 주어졌다면 확인할 수 있는 api이다. 

package main

import (
"fmt"
"flag"
"os"
)

func main() {
id := flag.String("id", "iiiii", "aaaaa")
name := flag.String("name", "nnnnn", "bbbbb")

if *id == "" || *name == "" {
flag.PrintDefaults()
os.Exit(1)
}

flag.Parse()
fmt.Println("id:", *id)
fmt.Println("name:", *name)
fmt.Printf("%v %v\n", *id, *name)

fmt.Println(flag.Args())
fmt.Println(flag.Arg(0))


}


결과는 다음과 같다.



./Test -id=1 -name=samuel a b c

id: 1

name: samuel

1 samuel

[a b c]

a


'golang' 카테고리의 다른 글

go 언어의 gc 소개 자료.  (0) 2018.07.19
[golang] 고루틴(go routine) 예제  (0) 2017.09.08
[golang] 에러(error) 예제  (0) 2017.09.07
[golang] defer 예제  (0) 2017.09.07
[golang] interface(인터페이스) 예제  (0) 2017.09.06
Posted by '김용환'
,


출처 :  http://news.naver.com/main/read.nhn?mode=LSD&mid=sec&sid1=105&oid=092&aid=0002122634 



홍콩 과기대 김성훈 교수(http://www.sciencetimes.co.kr/?news=%EC%A7%80%EB%B0%A9%EC%8B%A4%EC%97%85%EA%B3%A0-%EC%B6%9C%EC%8B%A0%EC%9D%B4-%ED%99%8D%EC%BD%A9%EA%B3%BC%EA%B8%B0%EB%8C%80-%EC%A1%B0%EA%B5%90%EC%88%98%EB%A1%9C)가 네이버 연구팀으로 합류한다고 한다. 



참고 : 김성훈 교수의 머신러닝 공부 내용 정리

https://hunkim.github.io/ml/ 



Posted by '김용환'
,