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

网站建设的数据库连接wordpress行情插件

网站建设的数据库连接,wordpress行情插件,设计网站推荐 zoo,自己创建公司Golang 并发 Cond条件变量 背景 编写代码过程中, 通常有主协程和多个子协程进行协作的过程,比如通过 WaitGroup 可以实现当所有子协程完成之后, 主协程再继续执行。 如上的场景是主协程等待子协程达到某个状态再继续运行。 但是反过来怎么…

Golang 并发 Cond条件变量

背景

编写代码过程中, 通常有主协程和多个子协程进行协作的过程,比如通过 WaitGroup 可以实现当所有子协程完成之后, 主协程再继续执行。

如上的场景是主协程等待子协程达到某个状态再继续运行。 但是反过来怎么操作呢,要求一组子协程等待主协达到某个状态时才继续运行。这个时候就需要用到 Cond 了

简介

Cond 是和某个条件相关,在条件还没有满足的时候,所有等待这个条件的协程都会被阻塞住,只有这个条件满足的时候,等待的协程才可能继续进行下去。Cond 在初始化的时候,需要关联一个 Locker 接口的实例,一般会使用 Mutex 或者 RWMutex。Cond 关联的 Locker 实例可以通过 c.L 访问,它内部维护着一个先入先出的等待队列。

Cond 分别有三个方法如下所示:

Wait

会把当前协程放入Cond的等待队列中并阻塞,直到被Signal或者Broadcast方法从等待队列中移除并唤醒,用于子协程阻塞。

Signal

主协程唤醒等待队列中的一个子协程,先唤醒最先阻塞的子协程,被唤醒的子协程继续执行。

Broadcast

主协程唤醒等待队列中的全部协程,所有子协程继续执行。

注意:调用 SignalBroadcast 方法,不强求持有c.L的锁,调用Wait方法是必须要持有c.L的锁。

Signal的使用场景

大家都去医院先排队,然后等待叫号,先排队的先叫号。这次模拟有5个病人,分别先排队。 然后护士根据排队先后来叫号;
具体场景是,5个病人在三秒中之内分别排号,护士今天要叫5个号,一秒叫一个,叫完5个号就结束了
代码如下:

func TestCondSignal(t *testing.T) {c := sync.NewCond(&sync.Mutex{})num := 0// 当前叫号是几号hand_num := 0for i := 0; i < 5; i++ {go func(i int) {// 分别在不同时间排队time.Sleep(time.Second * time.Duration(rand.Int63n(10)))c.L.Lock()num++// 当前取得号。cur := numfmt.Printf("%s  %d 号病人取到了 %d 号\n", time.Now().Format("2006-01-02 15:04:05"), i, cur)// 取到号了,等待叫号c.Wait()fmt.Printf("%s  %d 号病人排队号是 %d 号,被叫号了\n", time.Now().Format("2006-01-02 15:04:05"), i, cur)hand_num = curc.L.Unlock()}(i)}// 都叫号了for hand_num != 5 {// 叫号c.Signal()time.Sleep(time.Second * 1)}time.Sleep(time.Second * 10)
}

代码输出:

=== RUN   TestCondSignal
2024-02-06 13:49:55  0 号病人取到了 1 号
2024-02-06 13:49:56  4 号病人取到了 2 号
2024-02-06 13:49:56  3 号病人取到了 3 号
2024-02-06 13:49:56  0 号病人排队号是 1 号,被叫号了
2024-02-06 13:49:56  1 号病人取到了 4 号
2024-02-06 13:49:57  4 号病人排队号是 2 号,被叫号了
2024-02-06 13:49:58  3 号病人排队号是 3 号,被叫号了
2024-02-06 13:49:59  1 号病人排队号是 4 号,被叫号了
2024-02-06 13:50:02  2 号病人取到了 5 号
2024-02-06 13:50:02  2 号病人排队号是 5 号,被叫号了
--- PASS: TestCondSignal (18.09s)
PASS

结果表明,5个病人,分别在三秒钟内先后取号, 然后护士每过一秒钟按照排队的先后顺序叫一个号(叫号的过程依然有病人取号),先取号的被先叫号。
此场景中,5个病人相当于5个协程, 主协程反复使用Signal() 按照顺序一个个唤醒阻塞的子协程。

Broadcast的使用场景

场景为如下: 运动员跑步比赛,要求8秒内全部运动员准备好,然后等待教练发令, 教练10秒后发令,所有运动员在发令后开始跑。

func TestBroadcast(t *testing.T) {c := sync.NewCond(&sync.Mutex{})for i := 0; i < 10; i++ {go func(i int) {// 随机一个8秒内的准备时间time.Sleep(time.Second * time.Duration(rand.Int63n(8)))fmt.Printf("%s 运动员%d已准备就绪\n", time.Now().Format("2006-01-02 15:04:05"), i)c.L.Lock()// 准备完毕,等待教练发令c.Wait()c.L.Unlock()fmt.Printf("%s 运动员%d开跑\n", time.Now().Format("2006-01-02 15:04:05"), i)}(i)}// 主协程等待10秒后发令time.Sleep(time.Second * 10)fmt.Printf("%s 教练发令。\n", time.Now().Format("2006-01-02 15:04:05"))// 教练发令。通知所有运动员开始跑步, 即唤起之前 wait()的所有协程c.Broadcast()// 等待跑步time.Sleep(time.Second * 5)
}

代码输出如下

=== RUN   TestBroadcast
2024-02-06 13:56:57 运动员4已准备就绪
2024-02-06 13:56:57 运动员7已准备就绪
2024-02-06 13:56:58 运动员8已准备就绪
2024-02-06 13:56:58 运动员3已准备就绪
2024-02-06 13:56:59 运动员9已准备就绪
2024-02-06 13:57:00 运动员2已准备就绪
2024-02-06 13:57:01 运动员5已准备就绪
2024-02-06 13:57:02 运动员1已准备就绪
2024-02-06 13:57:03 运动员6已准备就绪
2024-02-06 13:57:04 运动员0已准备就绪
2024-02-06 13:57:07 教练发令。
2024-02-06 13:57:07 运动员0开跑
2024-02-06 13:57:07 运动员9开跑
2024-02-06 13:57:07 运动员8开跑
2024-02-06 13:57:07 运动员3开跑
2024-02-06 13:57:07 运动员4开跑
2024-02-06 13:57:07 运动员5开跑
2024-02-06 13:57:07 运动员2开跑
2024-02-06 13:57:07 运动员1开跑
2024-02-06 13:57:07 运动员6开跑
2024-02-06 13:57:07 运动员7开跑
--- PASS: TestBroadcast (15.01s)

如结果所示, 10个运动员在8秒内分别准备好,等待教练发令后,同时开跑。
此场景中,10个运动员相当于10个协程, 同时等待主协程的命令,使用Broadcast() 唤醒所有阻塞的子协程。

注意事项

使用 Cond,最容易踩的坑就是调用 Wait() 方法之前,调用者没有持有锁或没有检查辅助条件。在如上示例代码中,假如把调用 Wait() 方法前后的加锁和释放锁的代码注释掉,运行代码会 导致程序 panic 。原因是调用 Wait 方法 ,会先把调用者放入等待队列中,然后释放锁。此时如果在未持有锁时调用释放锁的方法,就会 导致程序 panic

Wait方法的使用

  1. Wait会自动释放c.L锁,并挂起调用者的goroutine,之后恢复执行
  2. Wait会在返回时对c.L加锁
  3. 除非被Broadcast或Signal唤醒,否则Wait不会返回
  4. 由于Wait第一次恢复是,c.L并没有加锁,所以当Wait返回时,调用者通常不能假设条件为真
  5. 简单来说,只要想使用condition就必须加锁

参考

https://www.jb51.net/article/277047.htm

http://www.yayakq.cn/news/710037/

相关文章:

  • 网站制作哪家便宜全球招商网加盟网
  • 网站服务公司哪个好淄博网站制作高端服务
  • 网站建设 山西大连手机模板建站
  • 建设一网站要多少钱购买网站开发服务费入账
  • 论述农产品电商网站建设上海外贸网站建设公司
  • 厦门博客网站制作黄陂机械加工网
  • 福建泉州做网站公司wordpress在哪注册
  • 做网站资源长沙网站外包公司
  • 服装设计素材网站邮箱号码大全
  • wordpress网站案例3d网络游戏前十名
  • 网站建设流程咨询一个做智能化的网站有哪些
  • 无锡专业网站建设公司如何更换网站域名
  • 做类似昵图网网站外省公司做网站备案
  • 网站推广的短视频推广电器网站建设免费咨询
  • 企业网站一般用什么域名网站备案 幕布
  • 青海建设厅网站尚少岩wordpress安卓版教程视频教程
  • 东莞做企业营销型网站的公司十大设计网站
  • 沈阳做网站 熊掌号重庆整站seo
  • 外贸网站网站建设微信网站怎么开发
  • 山西网站建设哪家好乾安网站建设公司电话
  • 网站建1设公司在家做网站
  • 微网站自己怎么做的吗流程页面设计
  • 网站开发php和c语言区别wordpress部署成英文怎么办
  • 融水县住房和城乡建设局网站智能小程序开发者工具
  • 建设系统网站网站建设团队
  • 建设银行锦州分行网站网站高级感
  • 帮别人做网站制作html网页素材
  • 小型网站开发需要什么步骤wordpress添加菜单选项
  • 如何建设股权众筹网站h5网站建设 网站定制开发
  • 房屋租赁网站建设如何给客户定位中国建设建行网站