10.1 Synchronizing 同步 access to a resource with Mutex

package main

import (
	"fmt"
	"sync"
)

var names = []string{"Alan", "Joe", "Jack", "Ben",
	"Ellen", "Lisa", "Carl", "Steve", "Anton", "Yo"}

type SyncList struct {
	m     sync.Mutex
	slice []interface{}
}

func NewSyncList(cap int) *SyncList {
	return &SyncList{
		sync.Mutex{},
		make([]interface{}, cap),
	}
}

func (l *SyncList) Load(i int) interface{} {
	l.m.Lock()
	defer l.m.Unlock()
	return l.slice[i]
}

func (l *SyncList) Append(val interface{}) {
	l.m.Lock()
	defer l.m.Unlock()
	l.slice = append(l.slice, val)
}

func (l *SyncList) Store(i int, val interface{}) {
	l.m.Lock()
	defer l.m.Unlock()
	l.slice[i] = val
}

func main() {

	l := NewSyncList(0)
	wg := &sync.WaitGroup{}
	wg.Add(10)
	for i := 0; i < 10; i++ {
		go func(idx int) {
			l.Append(names[idx])
			wg.Done()
		}(i)
	}
	wg.Wait()

	for i := 0; i < 10; i++ {
		fmt.Printf("Val: %v stored at idx: %d\n", l.Load(i), i)
	}

}

/*
Val: Joe stored at idx: 0
Val: Alan stored at idx: 1
Val: Jack stored at idx: 2
Val: Ellen stored at idx: 3
Val: Lisa stored at idx: 4
Val: Ben stored at idx: 5
Val: Carl stored at idx: 6
Val: Steve stored at idx: 7
Val: Anton stored at idx: 8
Val: Yo stored at idx: 9

*/

同步原语Mutex由包同步提供。互斥锁作为锁定在安全部分或资源之上。一旦goroutine里呼吁互斥锁和互斥锁在锁定状态,互斥被锁定和goroutine就进入临界区的互斥访问。如果互斥锁处于锁定状态,锁定的goroutine里调用方法。这个goroutine就堵塞了,需要等到再次得到解锁互斥。
注意,在示例中,我们使用互斥体在片原语上同步访问,这对于并发使用是不安全的。
重要的事实是互斥锁在第一次使用后不能复制。

posted @ 2018-03-27 00:31  cucy_to  阅读(124)  评论(0)    收藏  举报