This is the 16th day of my participation in the August More Text Challenge. For details, see:August is more challenging

Problems in accessing critical resources

Func f1() {for I := 0; for I := 0; for I := 0; i < 10000; I++ {x ++} wg.done ()} func main() {wg.add (2) // open the goroutine to access the critical resources go f1() go f1() go f1() wg.wait () FMT.Println("x = : ", x)}Copy the code

sync.Mutex

The lock is a mutex

When a goroutine acquires a mutex and has access to a critical section, other goroutines wait until the current goroutine that accesses a critical section unlocks the mutex before they can acquire the mutex again

Var (x = 0 warsync.waitgroup // Define a global Mutex lock sync.mutex) // Access the critical resource func f1() {for I := 0; i < 10000; Lock() x ++ // Unlock the resource after accessing it} wg.done ()} func main() {wg.add (2) // FMT.Println("x = : ", x)} go f1() go f1() wg.wait ()Copy the code

sync.RWMutex

In read locked state: Read locks can be added again, but write locks cannot be implemented

In the write locked state: Read and write locks cannot be performed again

// Define the global variable var (x = 0 warsync.waitGroup // Mutex //lock sync.mutex // read/write lock rwLock sync.rwmutex) // Read operation func read() {// Rwlock.rlock () time.sleep (time.millisecond * 10) rwlock.runlock () wg.done ()} func write() Rwlock.unlock () wg.done ()} func main() {now := time.now () for I := 0; i < 100; i++ { wg.Add(1) go write() } for i := 0; i < 100; I++ {wg.add (1) go read()} wg.wait () 21.997394ms 22.495443ms 22.509435ms /* There is an order of magnitude difference in the elapsed time between them, therefore: We need to write our code at the right time with the right lock */ fmt.println (time.now ().sub (Now))}Copy the code

sync.Once

A Once variable only executes one Do function

That is, for every function to be executed, a new Once variable is called

Var once1 sync.once var once2 sync.once func f1() {FMT.Println(" I am f1, I was executed ")} func f2() {FMT.Println(" I am f2, I was executed ")} func f2() {FMT.Println(" I am f2, I was executed ")} func f2() {FMT. ")} func main() {once1.do (f1) once2.do (f2)} once1.do (f1) once2.do (f2)} once1.do (f1) once2.do (f2)}Copy the code

Sync. Once source analysis

/* Once is a struct type with two variables: */ type Once struct {done uint32 m Mutex} /* Determine whether the done function is executed. */ func(o *Once) Do(f func()) {if atomic.LoadUint32(&o.one) == 0 {O.low (f)}} /* Lock the function first. Change the done flag bit, */ func(o *Once) doSlow(f func()) {o.m.lock () defer O.m.un lock() if O.one == 0 {defer atomic.StoreUint32(&o.done, 1) f() } }Copy the code

sync.Map

Var m sync.Map m.tore ("shaosiming", 18) m.tore ("dasiming", 20) FMT.Printf("%#v \n", m) Ok := m.load ("shaosiming") if ok {fmt.println (v)} // If the key exists, return the corresponding value and true, do not change the original value // If the key does not exist, return false and the stored value, Map v, ok = m.loadorStore ("dasiming2", 22) if ok {FMT.Println(v)} else {FMT.Println(v) FMT.Println(v)) v, If ok {FMT.Println(v)}} // delete the key ("dasiming3"); V, ok = m.loadandDelete ("dasiming3") if ok {fmt.Println(" deletion succeeded, value: ", v)} else {FMT.Println(" failed to delete data, value: Bool {FMT.Println("key: ", key, "value: ", key," value: ", key, "value: ", value) return true })Copy the code