상세 컨텐츠

본문 제목

Go Routines

Go lang

by techbard 2022. 3. 18. 20:29

본문

반응형
package main

import (
	"fmt"
	"time"
)

func main() {
	var msg string = "hello"

	go func() {
		fmt.Println(msg)
	}()

	msg = "goodbye" // why this is printed? (race condition with go routines)

	time.Sleep(100 * time.Microsecond)
}

// 결과
//
// goodbye

 

  • race condition의 해결
package main

import (
	"fmt"
	"time"
)

func main() {
	var msg string = "hello"

	go func(msg string) {
		fmt.Println(msg)
	}(msg)

	msg = "goodbye" // why this is printed? (race condition with go routines)

	time.Sleep(100 * time.Microsecond)
}

// 결과
//
// hello
package main

import (
	"fmt"
	"sync"
)

var wg = sync.WaitGroup{}

func main() {
	var msg = "hello"
	wg.Add(1)
	go func(msg string) {
		fmt.Println(msg)
		wg.Done()
	}(msg)
	msg = "goodbye"
	wg.Wait()
}

// 결과
//
// hello
package main

import (
	"fmt"
	"runtime"
	"sync"
)

var wg = sync.WaitGroup{}
var counter = 0
var m = sync.RWMutex{}

func main() {
	runtime.GOMAXPROCS(100)
	for i := 0; i < 10; i++ {
		wg.Add(2)
		go sayHello()
		go increment()
	}
	wg.Wait()
}

func sayHello() {
	m.RLock()
	fmt.Printf("Hello #%v\n", counter)
	m.RUnlock()
	wg.Done()
}

func increment() {
	m.Lock()
	counter++
	m.Unlock()
	wg.Done()
}

// 결과 (순서는 지켜지지만 순차는 아님)
//
// Hello #0
// Hello #1
// Hello #4
// Hello #4
// Hello #4
// Hello #6
// Hello #7
// Hello #8
// Hello #9
// Hello #10
package main

import (
	"fmt"
	"runtime"
	"sync"
)

var wg = sync.WaitGroup{}
var counter = 0
var m = sync.RWMutex{}

func main() {
	runtime.GOMAXPROCS(100)
	for i := 0; i < 10; i++ {
		wg.Add(2)
		m.RLock()
		go sayHello()
		m.Lock()
		go increment()
	}
	wg.Wait()
}

func sayHello() {
	fmt.Printf("Hello #%v\n", counter)
	m.RUnlock()
	wg.Done()
}

func increment() {
	counter++
	m.Unlock()
	wg.Done()
}

// 결과 (순서와 순차 모두 보장)
//
// Hello #0
// Hello #1
// Hello #2
// Hello #3
// Hello #4
// Hello #5
// Hello #6
// Hello #7
// Hello #8
// Hello #9

package main

import (
	"fmt"
	"sync"
)

var wg = sync.WaitGroup{}

func main() {
	ch := make(chan int)
	wg.Add(2)
	go func(ch <-chan int) {
		i := <-ch // receiving data from the channel.
		fmt.Println(i)
		wg.Done()
	}(ch)

	go func(ch chan<- int) {
		ch <- 42
		wg.Done()
	}(ch)
	wg.Wait()
}

// 결과
//
// 42

- Chammel basics
	. create a channel with make command
		. make(chan int)
	. Send message into channel
		. ch <- val
	. Receive message from channel
		. val := <-ch
	. Can have multiple senders and receivers
- Restricting data flow
	. Channel can be cast into send-only or receive only versions
		. Send-only: chan <- int
		. Receive-only: <-chan int
- Buffered channles
	. Channels block sender side till receiver is available
	. Block receiver side till message is available
	. Can decouple sender and receiver with buffered channels
		. make(chan int, 50)
	. Use buffered channels when send and receiver have assymmetric loading
- For...range loops with channels
	. Use to monitor channel and process messages as they arrive
	. Loop exits when channel is closed
- Select statements
	. Allows goroutine to monitor several channels at once
		. Blocks if all channels block
		. If multiple channels receive value simultaneously, behavior is undefined
반응형

관련글 더보기

댓글 영역