iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 9
0

今天不延用 BasicGo 的標題,並非 Concurrency 很困難,而是他在 golnag 中可以被輕易實踐,反而容易造成初學者的一些困擾與誤解,建議首次使用的朋友們慎重看待他。

Concurrency

In computer science, concurrency is the ability of different parts or units of a program, algorithm, or problem to be executed out-of-order or in partial order, without affecting the final outcome

以下圖為例,將兩個任務個別拆分成較小的子任務,並且同時丟到 thread 中執行,由於是同時丟入 thread 中,所以順序上無法保證哪一個任務先被處理完成。

圖片來源
Concurrency

範例

我們用一個簡單的範例,來觀察併發的情況有什麼不同。

  • serialize : 一般迴圈在沒有併發下,依序的印出0~4
  • concurrency : 而併發的 Println(),由於沒有刻意阻塞則同時印出了 0~4,但順序則非由小而大

concurrency/main.go

package main

import (
	"fmt"
	"time"
)

func main() {
	serialize()
	fmt.Println("-----")
	concurrency()
	time.Sleep(time.Second)
}

func serialize() {
	for i := 0; i < 5; i++ {
		fmt.Println(i)
		time.Sleep(500 * time.Millisecond) //為方便觀察睡一下
	}
}

func concurrency() {
	for i := 0; i < 5; i++ {
		//golang 併發的關鍵保留字 "go"
		go func(i int) {
			fmt.Println(i)
			time.Sleep(500 * time.Millisecond) //由於是同時進行,0~4將同時 sleep
		}(i)
	}
}

output

0
1
2
3
4
-----
4
1
0
3
2

衍生問題

由上面的範例可以觀察到,雖然可以將任務同時發出,但卻無法保證順序。那我們是否只能將相同且互不相干任務併發呢?答案是我們當然可以透夠一些方法,來進行同步也就是阻塞的動作,來達成將多個任務,依照合理的需求進行排列組合。

三種阻塞手段

  • Channel
  • Mutex Lock
  • Atomic

明日我們將會先介紹,沒處理好 goroutine 所產生的 data race 問題,並用三種阻塞手段控制我們的 goroutine。畢竟我們如果沒有滿足 ”without affecting the final outcome“ ,怎麼能算是 go consistently 呢?先讓我們從最小的地方也就是 memory consistency 做起吧!


上一篇
Day8 Basic Go (Initialize, Scope)
下一篇
Day10 Race Condition
系列文
Go Distributed & Go Consistently30

尚未有邦友留言

立即登入留言