iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 12
0
Software Development

Go Distributed & Go Consistently系列 第 12

Day12 Atomic

關於 sync/atomic 是於 go@v1.14 才推出的新東西,筆者也是最近才知道有這個包可以使用。Atomic 目標在一些單純的操作上,完成最小原子性操作,使用上甚至比 mutex 更為簡便。

Support Types

  • int32
  • uint32
  • int64
  • uint64
  • uintptr
  • unsafe.Pointer

Support Methods

  • Load : 讀取
  • Store : 寫入
  • Add : 加入
  • Swap : 交換
  • CompareAndSwap : 比對舊值後交換

支援的方法是依據資料型態提供,例如:AddInt32, AddInt64, AddUint64 ...,讓我們用一個簡單的範例看一下sync/atomic 的用法。

atomic/main.go

package main

import (
	"fmt"
	"sync/atomic"
	"time"
)

func main() {
	exampleCount()
}

func exampleCount() {
	var count int64
	timeStop := time.NewTimer(3 * time.Second)

	//每100ms讀寫一次
	go func() {
		t := time.NewTicker(100 * time.Millisecond)
		for {
			select {
			case <-t.C:
				atomic.AddInt64(&count, 1)
				fmt.Println(count)
			}
		}
	}()

	//每100ms讀寫一次
	go func() {
		t := time.NewTicker(100 * time.Millisecond)
		for {
			select {
			case <-t.C:
				atomic.AddInt64(&count, 1)
				fmt.Println(count)
			}
		}
	}()

	select {
	//預計執行 3s 60次
	case <-timeStop.C:
		time.Sleep(time.Millisecond) //防止最後一筆來不及寫入
		if count == 60 {
			fmt.Println("success")
		} else {
			fmt.Println("fail")
		}
	}
}

除了使用的方式外,我們當然也很在乎 atomic 的效能如何?以筆者自行測試的結果,速度優於 channel,約等同 mutex.Lock(),大家可以下載範例自行跑看看。根據筆者查到的資料,atomic package 底層是直接發送訊號跟 cpu 溝通,因此效能上會略優於在軟體層面實踐上鎖的 mutex package。但實測上差異實在是非常的小,如果不是對效能非常要求的服務,真的可以直接忽略效能的差異。

> go test -v -bench=.  -run=none -benchmem ./basicGo/atomic/atomic_test.go

goos: darwin
goarch: amd64
BenchmarkAtomic
BenchmarkAtomic-4        5705864               199 ns/op               0 B/op          0 allocs/op
BenchmarkMutex
BenchmarkMutex-4         6138507               221 ns/op               0 B/op          0 allocs/op
BenchmarkChannel
BenchmarkChannel-4       2330770               637 ns/op              69 B/op          0 allocs/op
PASS
ok      command-line-arguments  5.162s

小結

Day9 之後我們主題圍繞在, Concurrency(併發) 與 Race Condiction 上,為了處理內部同步問題,我們學習了 channel, mutex, atomic 三種方法,來幫助我們在併發的過程保持 memory consistency,避免發生不符合預期的資料產生。在我們會開始實作之前,會先介紹 docker 的使用方式,方便我們建立各種資料庫,也順便補充一些關於 container 的概念,以利後面篇幅的進行。


上一篇
Day11 Mutex vs Channel
下一篇
Day13 Docker
系列文
Go Distributed & Go Consistently30

尚未有邦友留言

立即登入留言