当前位置:网站首页>Go language ⌈ mutex and state coordination ⌋
Go language ⌈ mutex and state coordination ⌋
2022-04-23 02:08:00 【The breeze of the coast star】
List of articles
The mutex
Use a mutex to Go Secure access to data between collaborators .
package main
import (
"fmt"
"math/rand"
"runtime"
"sync"
"sync/atomic"
"time"
)
func main() {
// In our case ,`state` It's a map.
var state = make(map[int]int)
// there `mutex` Will synchronize with `state` The interview of .
var mutex = &sync.Mutex{}
// To compare the mutex based approach with the others we'll see later
// The way ,`ops` Will record our response to state The number of operations .
var ops int64 = 0
// Here we run 100 individual Go The coroutine reads repeatedly state.
for r := 0; r < 100; r++ {
go func() {
total := 0
for {
// Every loop reads , We use a key to access ,
// `Lock()` This `mutex` To make sure that `state` Of
// Exclusive access , Read the value of the selected key ,`Unlock()` This
// mutex, also `ops` It's worth adding 1.
key := rand.Intn(5)
mutex.Lock()
total += state[key]
mutex.Unlock()
atomic.AddInt64(&ops, 1)
// To make sure that Go The coordination process will not starve to death in scheduling , We
// Use... After each operation `runtime.Gosched()`
// To release . This release is usually handled automatically , Like for example
// After each channel operation or `time.Sleep` After the blocking call of
// be similar , But in this case, we need to deal with it manually .
runtime.Gosched()
}
}()
}
// alike , We run 10 individual Go To simulate write operations , Use
// The same mode as reading .
for w := 0; w < 10; w++ {
go func() {
for {
key := rand.Intn(5)
val := rand.Intn(100)
mutex.Lock()
state[key] = val
mutex.Unlock()
atomic.AddInt64(&ops, 1)
runtime.Gosched()
}
}()
}
// Let this 10 individual Go Association pair `state` and `mutex` The operation of
// function 1 s.
time.Sleep(time.Second)
// Get and output the final operation count .
opsFinal := atomic.LoadInt64(&ops)
fmt.Println("ops:", opsFinal)
// Yes `state` Use a final lock , Show how it ended .
mutex.Lock()
fmt.Println("state:", state)
mutex.Unlock()
}
Go State coprocess
In the previous example , We use mutexes for explicit locking so that shared state Across multiple Go Concurrent access . Another option is to use the built-in Go The same effect can be achieved by the synchronization characteristics of coprocessing and channel . This channel based approach and Go Through communication and every Go Coprocessors share memory through communication , Ensure that each piece of data has a separate Go All the ideas of the collaborative process are the same .
package main
import (
"fmt"
"math/rand"
"sync/atomic"
"time"
)
// In this case ,state Will be a separate Go The process has . This is
// It can ensure that the data will not be confused when reading in parallel . In order to state Conduct
// Read or write , Other Go The coroutine will send a piece of data to the owner Go
// In the process of cooperation , Then receive the corresponding reply . Structure `readOp` and `writeOp`
// Encapsulate these requests , And have Go One way of coprocessing response .
type readOp struct {
key int
resp chan int
}
type writeOp struct {
key int
val int
resp chan bool
}
func main() {
// Same as before , We will calculate the number of times we perform the operation .
var ops int64
// `reads` and `writes` The channels will be separated by other Go The process is used to send
// Read and write requests .
reads := make(chan *readOp)
writes := make(chan *writeOp)
// This is to have `state` the Go coroutines , And in the previous example
// map equally , But it's private to this state association . This Go coroutines
// Respond repeatedly to incoming requests . Respond to incoming requests first , Then return a value to
// Response channel `resp` To indicate that the operation is successful ( Or is it `reads` Requested value in )
go func() {
var state = make(map[int]int)
for {
select {
case read := <-reads:
read.resp <- state[read.key]
case write := <-writes:
state[write.key] = write.val
write.resp <- true
}
}
}()
// start-up 100 individual Go The agreement passed `reads` Channel initiated pair state owner
// Go Read request of coroutine . Each read request needs to construct a `readOp`,
// Send it to `reads` In the passage , And through the given `resp` Channel receive result .
for r := 0; r < 100; r++ {
go func() {
for {
read := &readOp{
key: rand.Intn(5),
resp: make(chan int)}
reads <- read
<-read.resp
atomic.AddInt64(&ops, 1)
}
}()
}
// Start... In the same way 10 Write operations .
for w := 0; w < 10; w++ {
go func() {
for {
write := &writeOp{
key: rand.Intn(5),
val: rand.Intn(100),
resp: make(chan bool)}
writes <- write
<-write.resp
atomic.AddInt64(&ops, 1)
}
}()
}
// Give Way Go The collaborators ran 1s.
time.Sleep(time.Second)
// Last , Obtain and report `ops` value .
opsFinal := atomic.LoadInt64(&ops)
fmt.Println("ops:", opsFinal)
}
版权声明
本文为[The breeze of the coast star]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204230206482586.html
边栏推荐
- Cc2541 emulator CC debugger tutorial
- Virtual serial port function of j-link V9 using skills
- php 2022年4月20面试题整理
- 2018 China Collegiate Programming Contest - Guilin Site J. stone game
- Hyperscan -- 2 compilation
- Common formatting problems after word writing
- A simple and open source navigation website source code
- 都是做全屋智能的,Aqara和HomeKit到底有什么不同?
- What is a dial-up server and what is its use?
- World Book Day 𞓜 a good book that technicians should not miss (it cutting-edge technology)
猜你喜欢
拨号服务器是什么,有什么用处?
013_基于Session实现短信验证码登录流程分析
【汇编语言】从最底层的角度理解“堆栈”
89 régression logistique prédiction de la réponse de l'utilisateur à l'image de l'utilisateur
Nanny level tutorial on building personal home page (II)
动态代理ip的测试步骤有哪些?
Cc2541 emulator CC debugger tutorial
Wechat public platform test number application, authorized login function and single sign on using hbuilder X and wechat developer tools
使用代理IP是需要注意什么?
Dynamic batch processing and static batch processing of unity
随机推荐
A simple and open source navigation website source code
How to configure iptables to realize local port forwarding
Heap overflow of kernel PWN basic tutorial
Some tips for using proxy IP.
go语言打怪通关之 ⌈互斥锁和状态协程⌋
postman里面使用 xdebug 断点调试
EBS:PO_EMPLOYEE_HIERARCHIES_ALL
[Dahua cloud native] micro service chapter - service mode of five-star hotels
Use of j-link RTT
Leetcode46 Full Permutation
What is BGP server and what are its advantages?
Introduction to esp32 Bluetooth controller API
Quel est le fichier makefile?
【汇编语言】从最底层的角度理解“堆栈”
World Book Day 𞓜 a good book that technicians should not miss (it cutting-edge technology)
LeetCode 283. Move zero (simple, array) Day12
PTA: 浪漫倒影 [二叉树重建] [深度优先遍历]
在使用代理IP前需要了解哪些分类?
拨号服务器是什么,有什么用处?
Echo "new password" |passwd -- stdin user name