current position:Home>[golang] walk into go language lesson 20 atomic operation & mutex

[golang] walk into go language lesson 20 atomic operation & mutex

2021-08-23 05:50:13 I'm Xiaobai

【Golang】️ Walk into Go Language ️ Lesson 20

summary

Golang Is a new cross platform programming language . Today, Xiaobai will take you hand in hand into Golang The world of . ( The first 20 course )

 Insert picture description here

Problems in the process

When a large number of concurrent processes , There will be a resource preemption conflict .

Example :

package main

import (
	"fmt"
	"time"
)

func main() {

	//  Defines the atomic variable integer 
	var ops uint64 = 0

	//  Create a collaborative process 
	for i := 0; i < 10; i++ {
		go func() {
			for j := 0; j < 10000; j++ {
			    //  Thread conflict ,  The data is not accurate 
				ops += 1
			}
		}()
	}

	//  wait for 
	time.Sleep(time.Second * 5)

	//  Debug output 
	fmt.Println(ops)

}

Output results :

69980

We can see , The output is zero 69980, Instead of 100000, The reason is that the data is inaccurate due to thread conflict .

Atomic manipulation

atomic The atomic operation provided enables us to ensure that there is only one co process at any time (go routine) Operate on variables . Make good use of atomic It can avoid a large number of lock operations in the program .

 Insert picture description here

Example :

package main

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

func main() {

	//  Defines the atomic variable integer 
	var ops uint64 = 0

	//
	for i := 0; i < 10; i++ {
		go func() {
			for j := 0; j < 10000; j++ {
				//  Avoid thread conflicts 	
				atomic.AddUint64(&ops, 1)
			}
		}()
	}

	//  wait for 
	time.Sleep(time.Second * 5)

	//  Debug output 
	fmt.Println(ops)

}

Output results :

100000

The mutex

The mutex (Mutex) Variables used for active control elements can only be accessed by one coroutine at a time .

Mutex There are two ways :

  • func (*Mutex) Lock: Lock The method locks m, If m Locked , Then block to m Unlock
  • func (*Mutex) Unlock: Unlock Method unlock m, If m Not locking will result in runtime errors

 Insert picture description here

Example :

package main

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


func main() {
	var state = make(map[int]int)  //  state 
	var mutex = &sync.Mutex{}  //  The mutex 
	var readops uint64 = 0  //  Reading data 
	var writeops uint64 = 0  //  Write data 


	//  Cyclic reading 
	for i := 0; i < 100; i++ {
		go func() {
			total := 0
			for {

				key := rand.Intn(5)
				mutex.Lock()  //  Lock 
				total += state[key]  //  Data overlay 
				mutex.Unlock()  //  Unlock 

				atomic.AddUint64(&readops, 1)  //  Record the number of reads 

				time.Sleep(time.Millisecond)
			}
		}()
	}

	//  Loop write 
	for i := 0; i < 10; i++ {
		go func() {
			for {
				key := rand.Intn(5)
				val := rand.Intn(100)
				mutex.Lock()  //  Lock 
				state[key] = val  //  Write data 
				mutex.Unlock()  //  Unlock 

				atomic.AddUint64(&writeops, 1)  //  Number of writes 
				time.Sleep(time.Millisecond)
			}
		}()
	}

	//  Sleep 1 second 
	time.Sleep(time.Second * 1)

	//  Debug output 
	read := atomic.LoadUint64(&readops)
	write := atomic.LoadUint64(&writeops)
	fmt.Println(read)
	fmt.Println(write)

	mutex.Lock()
	fmt.Println(state)
	mutex.Unlock()
	
}

Output results :

5179
519
map[0:36 1:67 2:62 3:86 4:68]

copyright notice
author[I'm Xiaobai],Please bring the original link to reprint, thank you.
https://en.qdmana.com/2021/08/20210823055009369d.html

Random recommended