Go从0开发(9)_并发/锁

互斥锁  Mutex

package main

import (
"fmt"
"sync"
)

var xx = 0
var wgs sync.WaitGroup
var lock sync.Mutex

func f2() {
defer wgs.Done()
for i := 0; i < 500000; i++ {
lock.Lock()
xx = xx + 1
lock.Unlock()
}
}

func main() {
wgs.Add(2)
go f2()
go f2()
wgs.Wait()
fmt.Println(xx)

}

读写锁 RWMutex

package main

import (
"fmt"
"sync"
"time"
)

//rwlock

var (
y = 0
locks sync.Mutex //互斥锁
ws sync.WaitGroup
rlock sync.RWMutex //读写互斥锁
)

func read() {
locks.Lock()
fmt.Println(y)
time.Sleep(time.Millisecond)
locks.Unlock()
defer ws.Done()
}

func read2() {
rlock.RLock() //加读锁
fmt.Println(y)
time.Sleep(time.Millisecond)
rlock.RUnlock()
defer ws.Done()
}

func write() {
locks.Lock()
y=y+1
time.Sleep(time.Millisecond*5)
locks.Unlock()
defer ws.Done()
}

func write2() {
rlock.Lock() //加写锁
y=y+1
time.Sleep(time.Millisecond*5)
rlock.Unlock()
defer ws.Done()
}

func main() {
//开始时间
start := time.Now()
for i := 0; i < 10; i++ {
ws.Add(1)
go write()
}

for i := 0; i < 1000; i++ {
ws.Add(1)
go read2()
}
ws.Wait()

//结束时间
end :=time.Now()
fmt.Println(end.Sub(start))
}

一个针对只执行一次场景 Once

package main

import (
"fmt"
"sync"
"time"
)

var str map[string]string
var ws sync.WaitGroup


func f1() {
str = map[string]string{
"name":"张",
"age":"16",
}
}

func f2(n string) string {
defer ws.Done()
if str == nil{
f1()
}
return str[n]
}

var icon sync.Once

func once(n string) string {
defer ws.Done()
icon.Do(f1) //只操作一次
return str[n]
}

func main() {
start := time.Now()

for i := 0; i < 1000; i++ {

ws.Add(1)
go func() {
ss := once("name")
fmt.Println(ss)
}()

}
ws.Wait()
end :=time.Now()
fmt.Println(end.Sub(start))
}


开箱即用的 map  (Go语言中内置的map不是并发安全的)

package main

import (
"fmt"
"sync"
)

var m sync.Map

func main() {
var ws sync.WaitGroup
for i:=0;i<21;i++{
ws.Add(1)
go func(n int) {
m.Store("name","张三") //设置键值对
val,_ := m.Load("name") //取值
fmt.Println(val)
ws.Done()
}(i)
}
ws.Wait()

}

网络 tcp

package main

import (
"fmt"
"net"
)

func pc(conn net.Conn) {
var tmp [128]byte
for{
n, err := conn.Read(tmp[:])
if err != nil {
fmt.Println("接收数据出错", err)
return
}

fmt.Println(string(tmp[:n]))
conn.Write(tmp[:n])
}
}

func main() {

///创建一个服务
listener, err := net.Listen("tcp", "127.0.0.1:3344")
if err != nil {
fmt.Println("服务启动", err)
return
}
defer listener.Close()

//接收数据
for {
//通信建立连接
conn, err := listener.Accept()
if err != nil {
fmt.Println("网络连接出错", err)
return
}

go pc(conn)
}
}



伍先生
  • 职业: 程序员,产品
  • 码龄: 8.7
  • 技能: PHP Go 前端
  • 微信: JwCode
  • 公众号/小程序: 渐悟分享