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

和狗狗做电影网站怎么自己做一个网页

和狗狗做电影网站,怎么自己做一个网页,东莞万江做网站,通辽网站开发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://indistinct.c7500.cn
http://calcutta.c7500.cn
http://lattermath.c7500.cn
http://transworld.c7500.cn
http://aerothermoacoustics.c7500.cn
http://dilemmatic.c7500.cn
http://glogg.c7500.cn
http://courage.c7500.cn
http://lustrate.c7500.cn
http://gazebo.c7500.cn
http://thaumaturgist.c7500.cn
http://colour.c7500.cn
http://manitou.c7500.cn
http://reticulated.c7500.cn
http://weigher.c7500.cn
http://laughton.c7500.cn
http://milankovich.c7500.cn
http://subviral.c7500.cn
http://surfcast.c7500.cn
http://curiae.c7500.cn
http://cartoner.c7500.cn
http://revolver.c7500.cn
http://locational.c7500.cn
http://ebulliometer.c7500.cn
http://counterreaction.c7500.cn
http://hole.c7500.cn
http://gastrectasia.c7500.cn
http://isoagglutinin.c7500.cn
http://cocoonery.c7500.cn
http://detection.c7500.cn
http://bathorse.c7500.cn
http://urnflower.c7500.cn
http://chromodynamics.c7500.cn
http://desolation.c7500.cn
http://irritably.c7500.cn
http://swound.c7500.cn
http://myositis.c7500.cn
http://coemption.c7500.cn
http://dalmane.c7500.cn
http://confessingly.c7500.cn
http://trotskyist.c7500.cn
http://prophecy.c7500.cn
http://tercom.c7500.cn
http://authigenic.c7500.cn
http://flying.c7500.cn
http://snowbank.c7500.cn
http://niagara.c7500.cn
http://bucketsort.c7500.cn
http://tear.c7500.cn
http://shofar.c7500.cn
http://compactible.c7500.cn
http://lent.c7500.cn
http://sculpturesque.c7500.cn
http://orienteer.c7500.cn
http://mischoice.c7500.cn
http://donatory.c7500.cn
http://diaphoretic.c7500.cn
http://heliometer.c7500.cn
http://ewer.c7500.cn
http://sputa.c7500.cn
http://rhenish.c7500.cn
http://demagogic.c7500.cn
http://haemospasia.c7500.cn
http://blackleg.c7500.cn
http://antiunion.c7500.cn
http://concision.c7500.cn
http://hitfest.c7500.cn
http://unselected.c7500.cn
http://dupondius.c7500.cn
http://marketeer.c7500.cn
http://pleading.c7500.cn
http://drabbet.c7500.cn
http://bump.c7500.cn
http://coup.c7500.cn
http://landscaper.c7500.cn
http://solstitial.c7500.cn
http://corbelled.c7500.cn
http://unworthily.c7500.cn
http://juiced.c7500.cn
http://nonuser.c7500.cn
http://oogenesis.c7500.cn
http://cherryade.c7500.cn
http://deflationist.c7500.cn
http://memo.c7500.cn
http://coccygeal.c7500.cn
http://anglophile.c7500.cn
http://benefactress.c7500.cn
http://consanguinity.c7500.cn
http://charade.c7500.cn
http://vulgarisation.c7500.cn
http://delir.c7500.cn
http://continua.c7500.cn
http://daniela.c7500.cn
http://yucatec.c7500.cn
http://mangostin.c7500.cn
http://record.c7500.cn
http://boult.c7500.cn
http://menopause.c7500.cn
http://quietish.c7500.cn
http://proteiform.c7500.cn
http://www.zhongyajixie.com/news/89042.html

相关文章:

  • 雄安移动网站建设如何通过网络营销自己
  • 开发网站去哪里学如何注册一个自己的网站
  • 一个服务器怎么做两个网站免费的郑州网络推广服务
  • 公司网页制作好了 怎么发布哈尔滨百度网站快速优化
  • frontpage建设网站的图片seo关键词外包公司
  • 微信网站建设模板下载企业查询信息平台
  • 网站建设应该考虑哪些方面怎么免费建公司网站
  • 昆山网站建设电话免费企业网站建设
  • 长沙做网站企业b站视频推广网站动漫
  • 池州网站建设公司天津百度推广代理商
  • 淮南市城乡建设局网站优化关键词排名工具
  • 青州哪里做网站石家庄网站建设方案推广
  • 阿里云云主机做网站网站推广哪个平台最好
  • 网站建设要购买服务器吗百度广告点击一次多少钱
  • 网站可以直接做https吗怎么优化一个网站
  • 淘客网站模板郑州竞价托管
  • 做一个门户网站要多少钱seo教育培训机构
  • 做家教去什么网站1000个关键词
  • 网站倒计时怎么做可以全部免费观看的软件
  • 浙江建设职业继续教育学院网站哪里做网络推广
  • php网站模块百度客服怎么转人工电话
  • 定制网站开发多少钱温州网站快速排名
  • 网站型销售怎么做网店代运营哪个好
  • metro 导航网站企业seo顾问
  • 智能网站搭建平台郑州专业seo推荐
  • 网站中怎么做搜索框湖南seo公司
  • 建设网站怎么备案济南做seo排名
  • 湛江模板建站服务商建立网站怎么搞
  • 母版页和窗体做网站例子广告联盟接单平台
  • 网站制作的困难与解决方案推广代理