golang sync

基本同步原语:

sync.Mutex:用于保护临界区域的互斥锁,例如:

var mu sync.Mutex

var count int

func increment() {

  mu.Lock()

  defer mu.Unlock()

  count++

}

sync.RWMutex:用于允许多个读操作和单个写操作的读写锁,例如:

var rwmu sync.RWMutex

var data map[string]string

func read(key string) string {

  rwmu.RLock()

  defer rwmu.RUnlock()

  return data[key]

}



func write(key, value string) {

  rwmu.Lock()

  defer rwmu.Unlock()

  data[key] = value

}

sync.WaitGroup:用于等待一组并发操作完成的同步工具,例如:

var wg sync.WaitGroup

func main() {

  urls := []string{"https://google.com", "https://bing.com", "https://yahoo.com"}

  for _, url := range urls {

    wg.Add(1)

    go fetch(url)

  }

  wg.Wait()

  fmt.Println("All done")

}



func fetch(url string) {

  defer wg.Done()

  resp, err := http.Get(url)

  if err != nil {

    fmt.Println(err)

    return

  }

  fmt.Println(resp.Status)

}

sync.Once:用于只执行一次的初始化操作,例如:

var once sync.Once

var db *sql.DB



func getDB() *sql.DB {

  once.Do(func() {

    db = sql.Open("mysql", "user:password@/dbname")

  })

  return db

}

sync.Cond:用于在满足某些条件时通知或等待其他 goroutine 的同步工具。

package main

import (
	"fmt"
	"sync"
)

func main() {
	var m sync.Mutex
	c := sync.NewCond(&m) // 创建一个条件变量,关联互斥锁m
	queue := make([]int, 0, 10)

	// 生产者
	producer := func(i int) {
		m.Lock() // 获取互斥锁
		defer m.Unlock()
		queue = append(queue, i) // 向队列中添加元素
		fmt.Println("producer:", i)
		c.Signal() // 发送信号给消费者
	}

	// 消费者
	consumer := func(i int) {
		m.Lock() // 获取互斥锁
		for len(queue) == 0 { // 如果队列为空,则等待信号
			c.Wait()
		}
		item := queue[0] // 取出队列中的第一个元素
		queue = queue[1:]
		fmt.Println("consumer:", i, item)
		m.Unlock() // 释放互斥锁
	}

	for i := 0; i < 10; i++ {
        go producer(i)
        go consumer(i)
    }
}

高级同步原语:

sync.Map:用于并发安全地存储键值对的映射类型,例如:

var m sync.Map

func main() {

	wg := &sync.WaitGroup{}

	wg.Add(2)

	go func() {

		defer wg.Done()

		m.Store("foo", "bar")

	}()

	go func() {

		defer wg.Done()

		m.Store("baz", "qux")

	}()

	wg.Wait()

	m.Range(func(key, value interface{}) bool {

		fmt.Println(key, value)

		return true

	})

}

sync.Pool:用于缓存和复用临时对象的池类型,例如:

type Buffer struct {
	buf []byte
}

var pool = &sync.Pool{

	New: func() interface{} {

		return &Buffer{}

	},
}

func main() {

	b := pool.Get().(*Buffer)

	b.buf = append(b.buf, []byte("hello")...)

	fmt.Println(string(b.buf))

	pool.Put(b)

}

sync/atomic 包:提供了一些原子操作函数,可以在不使用锁的情况下对整数、指针等进行安全地读写、增减、交换和比较。例如:

package main



import (

    "fmt"

    "sync"

    "sync/atomic"

)



func main() {



 var counter int64 = 0 // 定义一个 int64 类型的变量 counter,初始值为0 

 var wg sync.WaitGroup // 定义一个 WaitGroup 变量 wg,用于等待所有 goroutine 完成 

 wg.Add(10) // 设置 wg 的计数器为10,表示有10个 goroutine 需要等待 



 for i := 0; i < 10; i++ { // 启动10个 goroutine 来并发地增加 counter 的值 

     go func() { // 每个 goroutine 中执行以下操作 

         defer wg.Done() // 函数结束时通知 wg 计数器减一 

         for j := 0; j < 10000; j++ { // 循环10000次 

             atomic.AddInt64(&counter, 1) // 原子地将 counter 加一 

         }

     }()

 }



 wg.Wait() // 等待所有 goroutine 完成 

 fmt.Println(counter) // 输出 counter 的最终值,应该是100000 

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值