当前位置: 首页 > news >正文

温州市名城建设集团有限公司网站二级域名如何申请

温州市名城建设集团有限公司网站,二级域名如何申请,wordpress安装无法链接数据库,wordpress js代码编辑器插件Go 语言 sync 包使用教程 Go 语言的 sync 包提供了基本的同步原语,用于在并发编程中协调 goroutine 之间的操作。 1. 互斥锁 (Mutex) 互斥锁用于保护共享资源,确保同一时间只有一个 goroutine 可以访问。 特点: 最基本的同步原语&#x…

Go 语言 sync 包使用教程

Go 语言的 sync 包提供了基本的同步原语,用于在并发编程中协调 goroutine 之间的操作。

1. 互斥锁 (Mutex)

互斥锁用于保护共享资源,确保同一时间只有一个 goroutine 可以访问。

特点:

  • 最基本的同步原语,实现互斥访问共享资源
  • 有两个方法:Lock()Unlock()
  • 不可重入,同一个 goroutine 重复获取会导致死锁
  • 没有超时机制,锁定后必须等待解锁
  • 不区分读写操作,所有操作都是互斥的
  • 适用于共享资源竞争不激烈的场景
  • 性能高于 channel 实现的互斥机制
  • 不保证公平性,可能导致饥饿问题
import ("fmt""sync""time"
)func main() {var mutex sync.Mutexcounter := 0for i := 0; i < 1000; i++ {go func() {mutex.Lock()defer mutex.Unlock()counter++}()}time.Sleep(time.Second)fmt.Println("计数器:", counter)
}

2. 读写锁 (RWMutex)

当多个 goroutine 需要读取而很少写入时,读写锁比互斥锁更高效。

特点:

  • 针对读多写少场景优化的锁
  • 提供四个方法:RLock()RUnlock()Lock()Unlock()
  • 允许多个读操作并发进行,但写操作是互斥的
  • 写锁定时,所有读操作都会被阻塞
  • 有读锁定时,写操作会等待所有读操作完成
  • 写操作优先级较高,防止写饥饿
  • 内部使用 Mutex 实现
  • 比 Mutex 有更多开销,但在读多写少场景下性能更高
var rwMutex sync.RWMutex
var data map[string]string = make(map[string]string)// 读取操作
func read(key string) string {rwMutex.RLock()defer rwMutex.RUnlock()return data[key]
}// 写入操作
func write(key, value string) {rwMutex.Lock()defer rwMutex.Unlock()data[key] = value
}

3. 等待组 (WaitGroup)

等待组用于等待一组 goroutine 完成执行。

特点:

  • 用于协调多个 goroutine 的完成
  • 提供三个方法:Add()Done()Wait()
  • Add() 增加计数器,参数可为负数
  • Done() 等同于 Add(-1),减少计数器
  • Wait() 阻塞直到计数器归零
  • 计数器不能变为负数,会导致 panic
  • 可以重用,计数器归零后可以再次增加
  • 非常适合"扇出"模式(启动多个工作 goroutine 并等待全部完成)
  • 不包含工作内容信息,仅表示完成状态
  • 轻量级,开销很小
func main() {var wg sync.WaitGroupfor i := 0; i < 5; i++ {wg.Add(1) // 增加计数器go func(id int) {defer wg.Done() // 完成时减少计数器fmt.Printf("工作 %d 完成\n", id)}(i)}wg.Wait() // 等待所有 goroutine 完成fmt.Println("所有工作已完成")
}

4. 一次性执行 (Once)

Once 确保一个函数只执行一次,无论有多少 goroutine 尝试执行它。

特点:

  • 确保某个函数只执行一次
  • 只有一个方法:Do(func())
  • 即使在多个 goroutine 中调用也只执行一次
  • 常用于单例模式或一次性初始化
  • 内部使用互斥锁和一个标志位实现
  • 非常轻量级,几乎没有性能开销
  • 如果传入的函数 panic,视为已执行
  • 不能重置,一旦执行就不能再次执行
  • 传入不同的函数也不会再次执行
var once sync.Once
var instance *singletonfunc getInstance() *singleton {once.Do(func() {instance = &singleton{}})return instance
}

5. 条件变量 (Cond)

条件变量用于等待或宣布事件的发生。

特点:

  • 用于等待或通知事件发生
  • 需要与互斥锁结合使用:sync.NewCond(&mutex)
  • 提供三个方法:Wait()Signal()Broadcast()
  • Wait() 自动解锁并阻塞,被唤醒后自动重新获取锁
  • Signal() 唤醒一个等待的 goroutine
  • Broadcast() 唤醒所有等待的 goroutine
  • 适合生产者-消费者模式
  • 可以避免轮询,提高性能
  • 使用相对复杂,容易出错
  • 等待必须在获取锁后调用
var mutex sync.Mutex
var cond = sync.NewCond(&mutex)
var ready boolfunc main() {go producer()// 消费者mutex.Lock()for !ready {cond.Wait() // 等待条件变为真}fmt.Println("数据已准备好")mutex.Unlock()
}func producer() {time.Sleep(time.Second) // 模拟工作mutex.Lock()ready = truecond.Signal() // 通知一个等待的 goroutine// 或使用 cond.Broadcast() 通知所有等待的 goroutinemutex.Unlock()
}

6. 原子操作 (atomic)

对于简单的计数器或标志,可以使用原子操作包而不是互斥锁。

特点:

  • 底层的原子操作,无锁实现
  • 适用于简单的计数器或标志位
  • 比互斥锁性能更高,开销更小
  • 提供多种原子操作:AddLoadStoreSwapCompareAndSwap
  • 支持多种数据类型:int32、int64、uint32、uint64、uintptr 和指针
  • 可用于实现自己的同步原语
  • 不适合复杂的共享状态
  • 在多 CPU 系统上可能导致缓存一致性开销
  • Go 1.19 引入了新的原子类型
import ("fmt""sync/atomic""time"
)func main() {var counter int64 = 0for i := 0; i < 1000; i++ {go func() {atomic.AddInt64(&counter, 1)}()}time.Sleep(time.Second)fmt.Println("计数器:", atomic.LoadInt64(&counter))
}

7. Map (sync.Map)

Go 1.9 引入的线程安全的 map。

特点:

  • Go 1.9 引入的线程安全的哈希表
  • 无需额外加锁即可安全地并发读写
  • 提供五个方法:StoreLoadLoadOrStoreDeleteRange
  • 内部使用分段锁和原子操作优化性能
  • 适用于读多写少的场景
  • 不保证遍历的顺序
  • 不支持获取元素数量或判断是否为空
  • 不能像普通 map 那样直接使用下标语法
  • 性能比加锁的普通 map 更好,但单线程下比普通 map 慢
  • 内存开销较大
var m sync.Mapfunc main() {// 存储键值对m.Store("key1", "value1")m.Store("key2", "value2")// 获取值value, ok := m.Load("key1")if ok {fmt.Println("找到键:", value)}// 如果键不存在则存储m.LoadOrStore("key3", "value3")// 删除键m.Delete("key2")// 遍历所有键值对m.Range(func(key, value interface{}) bool {fmt.Println(key, ":", value)return true // 返回 false 停止遍历})
}

8. Pool (sync.Pool)

对象池用于重用临时对象,减少垃圾回收压力。

特点:

  • 用于缓存临时对象,减少垃圾回收压力
  • 提供两个方法:Get()Put()
  • 需要提供 New 函数来创建新对象
  • 对象可能在任何时候被垃圾回收,不保证存活
  • 在 GC 发生时会清空池中的所有对象
  • 不适合管理需要显式关闭的资源(如文件句柄)
  • 适合于频繁创建和销毁的对象
  • 没有大小限制,Put 总是成功的
  • 每个 P(处理器)有自己的本地池,减少竞争
  • Go 1.13 后大幅提升了性能
var bufferPool = sync.Pool{New: func() interface{} {return new(bytes.Buffer)},
}func process() {// 获取缓冲区buffer := bufferPool.Get().(*bytes.Buffer)buffer.Reset() // 清空以便重用// 使用缓冲区buffer.WriteString("hello")// 操作完成后放回池中bufferPool.Put(buffer)
}

9. 综合示例

下面是一个综合示例,展示了多个同步原语的使用:

package mainimport ("fmt""sync""time"
)type SafeCounter struct {mu sync.Mutexwg sync.WaitGroupcount int
}func main() {counter := SafeCounter{}// 启动 5 个 goroutine 增加计数器for i := 0; i < 5; i++ {counter.wg.Add(1)go func(id int) {defer counter.wg.Done()for j := 0; j < 10; j++ {counter.mu.Lock()counter.count++fmt.Printf("Goroutine %d: 计数器 = %d\n", id, counter.count)counter.mu.Unlock()// 模拟工作time.Sleep(100 * time.Millisecond)}}(i)}// 等待所有 goroutine 完成counter.wg.Wait()fmt.Println("最终计数:", counter.count)
}

最佳实践

  1. 使用 defer 解锁:确保即使发生错误也能解锁

    mu.Lock()
    defer mu.Unlock()
    
  2. 避免锁的嵌套:容易导致死锁

  3. 保持临界区简短:锁定时间越短越好

  4. 基准测试比较

    • 对于大多数简单操作,atomic 比 Mutex 快
    • RWMutex 在读操作远多于写操作时优于 Mutex
    • sync.Map 在高并发下比加锁的 map 性能更好
  5. 内存对齐

    • 原子操作需要内存对齐
    • 不正确的内存对齐会严重影响性能
    • 特别是在 32 位系统上使用 64 位原子操作
  6. 超时控制

    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()done := make(chan struct{})
    go func() {// 执行可能耗时的操作mu.Lock()// ...mu.Unlock()done <- struct{}{}
    }()select {
    case <-done:// 操作成功完成
    case <-ctx.Done():// 操作超时
    }
    
http://www.dtcms.com/a/557170.html

相关文章:

  • 【C++】模拟算法习题
  • QLoRA基础知识和微调原理学习
  • 在 vscode 中配置juypter notebook 插件
  • 石家庄好用的招聘网站门户网站网站建设
  • ENERGY Designer:重构跨平台GUI开发的高效解决方案
  • 网站建设要准备什么资料wordpress回复下载
  • RabbitMQ 在拼团系统中的应用:延迟队列、订单超时与消息幂等
  • 【printpdf】color.rs 文件解析
  • Langchain4j 实战 【AI代码生成平台】:接入deepseek,开发AI服务并实现结构化输出
  • DNR6521x_VC1:革新音频体验的AI降噪处理器
  • 长沙做网站的公司哪家最好永久有效的代理ip
  • 技术准备九:FFmpeg
  • Jenkins 实战4:集群配置与分布式构建
  • 一人开公司做网站创业企业网站建设总结报告
  • android 15.0 app应用安装黑名单
  • N-158基于微信小程序学生社团管理系统
  • LeetCode算法日记 - Day 89: 最长递增子序列
  • 两学一做 网站帮别人建网站赚钱吗
  • 2025江苏省职业院校技能大赛网络系统管理赛项模块A:网络构建卷I(未公开)
  • 鸿蒙工程结构、开发指南
  • Python为什么能成为Ubuntu官方支持的脚本语言?
  • Studio Drummer 深度指南:从采样逻辑到风格化创作的实战手册
  • 一个专门做试题的网站商品seo关键词优化
  • 汽车ECU测试中边界值方法
  • 微信小程序开发工具软件网络优化策划书
  • 【GSR】皮肤电反应 数据分析全流程教程
  • 现代Python开发环境搭建(VSCode + Dev Containers)
  • 网站模版如何使用个人网站经营性备案查询
  • 理解计算机系统_程序计数器PC的实现
  • 在Unity中运行Yolo推理