网站一般宽度是多少像素/免费刷赞网站推广免费

网站一般宽度是多少像素,免费刷赞网站推广免费,做网站的公司成本,dede网站修改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.mzph.cn/pingmian/73613.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ubuntu22.04安装搜狗输入法保姆教程~

一、添加中文语言支持 1.首先打开设置,找到Language and Region 2.点击Manage Installed Languages 3.点击 Install/Remove Languages... 4.选中Chinese (simplified),点击Apply

强化学习和智能决策:Q-Learning和Deep Q-Learning算法

强化学习(Reinforcement Learning, RL)是机器学习的一个重要分支,它通过智能体(Agent)与环境交互来学习最优决策策略,旨在最大化智能体的长期累积奖励。Q-Learning和Deep Q-Learning是强化学习中的两种关键算法,它们在智能决策领域发挥着重要作用。 一、强化学习基础 …

ubuntu22.04 安装Jitsi meet 开源会议系统,代替腾讯会议

0.安装 官方安装教程Self-Hosting Guide - Debian/Ubuntu server | Jitsi Meet 一定要用域名访问&#xff0c; 一定要用域名访问&#xff0c; 一定要用域名访问&#xff0c; 一定要用域名访问&#xff0c; 域名一定要有ssl证书&#xff0c;域名一定要有ssl证书&#xff0c;域名…

专家管理系统(源码+文档+讲解+演示)

引言 在知识经济时代&#xff0c;专家管理系统成为了企业优化知识资源、提升决策效率的重要工具。本文将介绍一款创新的专家管理系统&#xff0c;该系统通过智能化工具&#xff0c;助力企业实现专家资源的高效管理和利用。 平台概述 专家管理系统采用前后端分离的架构设计&a…

关于cmd中出现无法识别某某指令的问题

今天来解决以下这个比较常见的问题&#xff0c;安装各种软件都可能会发生&#xff0c;一般是安装时没勾选注册环境变量&#xff0c;导致cmd无法识别该指令。例如mysql&#xff0c;git等&#xff0c;一般初学者可能不太清楚。 解决这类问题最主要的是了解环境变量的概念&#x…

【C++初阶】---类和对象(上)

1.类的定义 1.1类的定义格式 • class为定义类的关键字&#xff0c;Data为类的名字&#xff0c;{}中为类的主体&#xff0c;注意类定义结束时后⾯分号不能省略。类体中内容称为类的成员&#xff1a;类中的变量称为类的属性或成员变量;类中的函数称为类的⽅法或者成员函数。 •…

Rust安装并配置配置vscode编译器

一. 下载rustup-init.exe rust下载网址&#xff1a;Getting started - Rust Programming Language 根据系统&#xff0c;选择适合的exe文件 我选择的的是右边64bit的 打开下载的文件 输入1&#xff0c;回车 二. Visual C 安装 自动下载安装vs 等待安装完毕 三. Rust 安装…

ECharts各类炫酷图表/3D柱形图

一、前言 最近鸡米花实现了各类的炫酷的图表&#xff0c;有3D柱形图、双边柱形图以及异形柱形图&#xff0c;好了&#xff0c;直接上图&#xff1a; 二、效果图 一个个来吧&#xff0c;下面就是代码啦&#xff0c;注意&#xff0c;一下图表展示的宽高均为800px*300px 三、异形横…

HCIP——园区网、VLAN

园区网 园区网搭建核心思路&#xff1a;冗余&#xff08;备份&#xff09;--- 保证其健壮性 1、设备冗余 2、线路冗余 3、网关冗余 4、ups&#xff08;不间断电源&#xff09;冗余—— 能不断电&#xff08;物理层&#xff09; 三层交换机和路由器的选择&#xff1a; 三层交换…

虚拟机(二):Android 篇

虚拟机&#xff08;一&#xff09;&#xff1a;Java 篇 虚拟机&#xff08;二&#xff09;&#xff1a;Android 篇 Dalvik和JVM区别 Dalvik 基于寄存器&#xff0c;而 JVM 基于栈。 基于栈的架构具有更好的可移植性&#xff0c;因为其实现不依赖于物理寄存器基于栈的架构通常指…

Vue Kubernetes项目 局部布局 下拉菜单

下拉菜单 [el-dropdown] 下拉菜单也比较简单&#xff0c;就是类似于按钮下面来一个下拉菜单。 示例Demo如下&#xff1a; <template><el-dropdown><span class"el-dropdown-link">下拉菜单<i class"el-icon-arrow-down el-icon--right&q…

Android之卡片式滑动

文章目录 前言一、效果图二、实现步骤1.主界面xml2.自定义的viewpage3.卡片接口类4.阴影和缩放变化类5.卡片adapter6.卡片adapter的xml7.style8.CardItem9.activity实现10.指示器drawable 总结 前言 对于这个需求&#xff0c;之前的项目也有做过&#xff0c;但是过于赶项目就没…

(UI自动化测试web端)第二篇:元素定位的方法_css定位之css选择器

看代码里的【find_element_by_css_selector( )】( )里的表达式怎么写&#xff1f; 文章介绍了第三种写法css选择器&#xff0c;你要根据网页中的实际情况来判断自己到底要用哪一种方法来进行元素定位。每种方法都要多练习&#xff0c;全都熟了之后你在工作当中使用起来元素定位…

使用vscode搭建pywebview集成vue项目示例

文章目录 前言环境准备项目源码下载一、项目说明1 目录结构2 前端项目3 后端项目获取python安装包(选择对应版本及系统) 三、调试与生成可执行文件1 本地调试2 打包应用 四、核心代码说明1、package.json2、vite.config.ts设置3、main.py后端入口文件说明 参考文档 前言 本节我…

C stm32f10x LED亮

#include<stm32f10x.h>int main(){#if 0 //APIOA 时钟初始化unsigned int * p(unsigned int*)0x40021018;*p | 0x1<<2;//A0 推挽输出p(unsigned int*)0x40010800;*p *p & ~0xf | 0x1;//A0低电平p(unsigned int*)0x4001080c;*p & ~0x1;#endifRCC->APB2E…

redux ,react-redux,redux-toolkit 简单总结

Redux、React-Redux 和 Redux Toolkit 是协同工作的三个库&#xff0c;各自承担不同角色&#xff0c;相互协同。 Redux&#xff1a;基础底座 底层状态管理库&#xff0c;负责状态存储、Action 派发和 Reducer 执行 ​React-Redux&#xff1a;连接 React 组件与 Redux Store 通…

智能制造:物联网和自动化之间的关系

工业自动化 工业自动化是机器设备或生产过程在不需要人工直接干预的情况下按预期的目标实现测量、操纵等信息处理和过程控制的统称。 在传统的工业生产过程中&#xff0c;很多环节需要人工操作&#xff0c;比如设备调试、生产监控、质量检测等。然而&#xff0c;随着工业自动化…

集成学习(下):Stacking集成方法

一、Stacking的元学习革命 1.1 概念 Stacking&#xff08;堆叠法&#xff09; 是一种集成学习技术&#xff0c;通过组合多个基学习器&#xff08;base learner&#xff09;的预测结果&#xff0c;并利用一个元模型&#xff08;meta-model&#xff09;进行二次训练&#xff0c…

vmware虚拟机突然连不上网

1.一般是自己的主机把服务给关掉了&#xff0c;右击我的电脑&#xff0c;然后找到管理->服务&#xff0c;确保下面虚拟机的网络服务是否打开 Vmware虚拟机突然连接不上网络【方案集合】_vmware虚拟机连不上网-CSDN博客 2.识别到无效网络 控制面板->网络和共享中心&…

【JavaScript 简明入门教程】为了Screeps服务的纯JS入门教程

0 前言 0-1 Screeps: World 众所不周知&#xff0c;​Screeps: World是一款面向编程爱好者的开源大型多人在线即时战略&#xff08;MMORTS&#xff09;沙盒游戏&#xff0c;其核心机制是通过编写JavaScript代码来控制游戏中的单位&#xff08;称为“Creep”&#xff09;&#…