范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

Go并发编程指南第一篇

  竞争条件和数据竞争
  当两个或多个操作必须以正确的顺序执行时,就会出现竞争条件,但程序尚未编写为保证维护此顺序。
  数据竞争是指一个并发操作试图读取一个变量,而在某个不确定的时间另一个并发操作试图写入同一个变量。main func 是主 goroutine。 func main() {     var data int     go func() {         data++     }()      if data == 0 {         fmt.Printf("the value is %d", data)     } }sync内存访问同步
  sync 包包含对低级内存访问同步最有用的并发原语。临界区是代码中可以访问共享内存的地方mutex互斥体
  Mutex 代表"互斥",是一种保护程序关键部分的方法。 type Counter struct {     mu sync.Mutex     value int }  func (c *Counter) Increment() {     c.mu.Lock()     defer c.mu.Unlock()     c.value++ }waitgroup等待组
  调用添加一组goroutines var wg sync.WaitGroup for _, salutation := range []string{"hello", "greetings", "good day"} {     wg.Add(1)     go func(salutation string) {          defer wg.Done()         fmt.Println(salutation)     }(salutation)  } wg.Wait()读写互斥锁
  更细粒度的内存控制,可以请求只读锁 producer := func(wg *sync.WaitGroup, l sync.Locker) {      defer wg.Done()     for i := 5; i > 0; i-- {         l.Lock()         l.Unlock()         time.Sleep(1)      } }  observer := func(wg *sync.WaitGroup, l sync.Locker) {     defer wg.Done()     l.Lock()     defer l.Unlock() }  test := func(count int, mutex, rwMutex sync.Locker) time.Duration {     var wg sync.WaitGroup     wg.Add(count+1)     beginTestTime := time.Now()     go producer(&wg, mutex)     for i := count; i > 0; i-- {         go observer(&wg, rwMutex)     }      wg.Wait()     return time.Since(beginTestTime) }  tw := tabwriter.NewWriter(os.Stdout, 0, 1, 2, " ", 0) defer tw.Flush()  var m sync.RWMutex fmt.Fprintf(tw, "Readers	RWMutex	Mutex ")  for i := 0; i < 20; i++ {     count := int(math.Pow(2, float64(i)))     fmt.Fprintf(         tw,         "%d	%v	%v ",         count,         test(count, &m, m.RLocker()),         test(count, &m, &m),     ) }cond条件
  如果有某种方法可以让 goroutine 有效地休眠,直到收到唤醒并检查其状态的信号,那就更好了。这正是 Cond 类型为我们所做的。
  Cond 和 Broadcast 是用于通知在 Wait 调用中阻塞的 goroutines 条件已被触发的方法。 type Button struct {     Clicked *sync.Cond }  func main() {     button := Button{         Clicked: sync.NewCond(&sync.Mutex{}),     }      // running on goroutine every function that passed/registered     // and wait, not exit until that goroutine is confirmed to be running     subscribe := func(c *sync.Cond, param string, fn func(s string)) {         var goroutineRunning sync.WaitGroup         goroutineRunning.Add(1)          go func(p string) {             goroutineRunning.Done()             c.L.Lock() // critical section             defer c.L.Unlock()              fmt.Println("Registered and wait ... ")             c.Wait()              fn(p)         }(param)          goroutineRunning.Wait()     }      var clickRegistered sync.WaitGroup      for _, v := range []string{         "Maximizing window.",         "Displaying annoying dialog box!",         "Mouse clicked."} {          clickRegistered.Add(1)          subscribe(button.Clicked, v, func(s string) {             fmt.Println(s)             clickRegistered.Done()         })     }      button.Clicked.Broadcast()      clickRegistered.Wait() }Once
  确保即使在多个 goroutine 之间也只执行一次 var count int  increment := func() {     count++ }  var once sync.Once  var increments sync.WaitGroup increments.Add(100)  for i := 0; i < 100; i++ {     go func() {         defer increments.Done()         once.Do(increment)     }() }  increments.Wait() fmt.Printf("Count is %d ", count)Pool
  管理连接池,数量 package main  import (     "fmt"     "sync" )  func main() {     myPool := &sync.Pool{         New: func() interface{} {             fmt.Println("Creating new instance.")              return struct{}{}         },     }      // Get call New function defined in pool if there is no instance started     myPool.Get()     instance := myPool.Get()     fmt.Println("instance", instance)      // here we put a previously retrieved instance back into the pool,      // this increases the number of instances available to one     myPool.Put(instance)      // when this call is executed, we will reuse the      // previously allocated instance and put it back in the pool     myPool.Get()      var numCalcsCreated int     calcPool := &sync.Pool{         New: func() interface{} {             fmt.Println("new calc pool")              numCalcsCreated += 1             mem := make([]byte, 1024)              return &mem         },     }      fmt.Println("calcPool.New", calcPool.New())      calcPool.Put(calcPool.New())     calcPool.Put(calcPool.New())     calcPool.Put(calcPool.New())     calcPool.Put(calcPool.New())      calcPool.Get()      const numWorkers = 1024 * 1024     var wg sync.WaitGroup     wg.Add(numWorkers)      for i := numWorkers; i > 0; i-- {         go func() {             defer wg.Done()              mem := calcPool.Get().(*[]byte)             defer calcPool.Put(mem)              // Assume something interesting, but quick is being done with             // this memory.         }()     }      wg.Wait()     fmt.Printf("%d calculators were created.", numCalcsCreated) }死锁
  死锁是其中所有并发进程都在等待彼此。 package main  import (     "fmt"     "sync"     "time" )  type value struct {     mu    sync.Mutex     value int }  func main() {     var wg sync.WaitGroup     printSum := func(v1, v2 *value) {         defer wg.Done()         v1.mu.Lock()         defer v1.mu.Unlock()          // deadlock         time.Sleep(2 * time.Second)         v2.mu.Lock()         defer v2.mu.Unlock()          fmt.Printf("sum=%v ", v1.value+v2.value)     }      var a, b value     wg.Add(2)     go printSum(&a, &b)     go printSum(&b, &a)      wg.Wait() }
  总结
  本文是go语言并发编程指南最佳实践第一篇,后续第二篇还会整理各种channel的特性,锁的使用在并发编程中的特点与各种用途举例,全部都是最接地气的代码示例。关注我,敬请期待下一篇。

败人品!潘长江和64岁老戏骨直播卖茅台酒,4千多的酒卖2万801。hr对于明星直播带货一事,网友们的看法呈现出了两个极端,有人觉得明星赚钱已经比普通人简单多了,好好演戏就行,没必要隔行取利,有人觉得明星带货是为粉丝谋福利,他们有更好的渠道!iPhone13Pro一降再降,128GB版本已跌至新低,苹果13都不香了预算比较低,但又想购买苹果手机,那么其实可以考虑接下来登场的苹果iPhoneSE系列新机,种种迹象均表明苹果公司有望在三月份发布最新的iPhoneSE3,其定价预计会在3299元左德邦遗憾退场!快递行业迎来大洗牌,刘强东这次下了一步好棋想要便宜就用三通一达,想要服务好速度快就用京东和顺丰,想要寄大件那就用德邦,这是消费者们达成的共识,但在以后,消费者想寄大件可能要换家公司了。据最新消息报道,京东已经完成了对德邦快谢娜今年颜值狂飙太牛!新综造型曝光变化太大,穿亮色美成女神脸谢娜的新综朋友请听好最新季已经开播,并且受到了大家不少的好评,在这档节目中,谢娜可是展现了和大本营完全不同的主持风格,更加稳重的感觉也让大家看到了尤为出彩的谢娜。而除此之外,谢娜在喜剧演员白凯南的狼狈当时代抛弃他的时候,所有观众都在鼓掌欢乐喜剧人第六季是白凯南近些年参加过最火的综艺节目了,这也是他翻身的最好机会。可惜一切又被白凯南搞砸了,被指抄袭的他不仅没有成功咸鱼翻身,人气口碑还一夜之间下滑到了谷底。节目中的白唐鉴军戏里奸诈狡猾,戏外尊师重道,不负不孕妻子不负赵本山文拉丝怪听到唐鉴军三个字,大家可能会愣住,这是谁?但是喜欢看乡村爱情的人要听到广坤叔这个名字,大家肯定心中提起一团小怒火。因为这个灵魂角色在剧中有的时候可太气人了。虽然,广坤叔风评特伦特我们全队都憎恨德拉季奇,纳什根本没能力率领篮网夺冠今天篮网队迎来和猛龙的较量,由于猛龙队的主场有防疫规定,因此欧文并不能上场比赛,而德拉季奇之前曾效力于这里,不过当时他表示自己不想为猛龙打球了,随后就申请交易离队,随后和马刺完成买乒乓球接发球用好三点一向一加速盯球法,判断上下旋不再愁乒乓球最难的是接发球,接发球难就难在盯旋转上,尤其是盯上下旋。我们许多业余球友在接发球时,不会判断上旋和下旋,经常下网或出界,尤其对相似动作发出的上下旋迷惑球,更是苦不堪言。其实,拒绝背锅,篮网代理主教练临场积极求变,证明自己不只是走走过场背靠背再战猛龙,篮网代理主教练沃恩的临场指挥可圈可点。这场比赛,沃恩明显吸取了上一场比赛任由猛龙快节奏推进,然后各种得分的教训,让队员加强争抢对抗和防守,有时甚至不惜以犯规为代价。没人要布朗尼?你爹来签你!曝老詹将成为新球队老板,或为儿铺路谈到詹姆斯这位超级巨星时,我们常拿他和乔丹做比较,但二人的打法完全不同,乔丹凭借干净利落的突破和行云流水般的中投肆虐着联盟。而詹姆斯则不同,早期凭借劲爆的素质和爆发力冲击篮下,现在神奇点心店解忧杂货店,红子钱天堂,淀淀倒霉堂,不分上下神奇点心店文青源阳阳日本现象级儿童文学神奇点心店真好看。神奇点心店是一套包含了四本书籍的现象级儿童文学作品,作者是广岛玲子,仲雷雷翻译,加加绘画,把我们一下子带到了儿童解忧杂货店的
海报观潮丨打开更好的山东,看诗和远方相融共生来源海报新闻5年前,在国务院机构改革中,文化和旅游部被组建起来。很多网友感叹说诗和远方终于可以在一起了。确实,诗,文学的一种形式,属于文化范畴旅游,发生在时间和空间中的穿行,又往往女人觉得最浪漫的十件事情女人觉得最浪漫的十件事情1。惊喜礼物无论是礼物本身还是送礼的方式,都能让女人感到浪漫。例如,给她们一个意料之外的生日礼物或在一个特殊的日子送礼物。2。旅游带她们去一个令人兴奋的旅游山东大区雨水酿酒竞赛各分段情况今天中午12点,本次巽风雨水酿酒竞赛落下帷幕,由于电子卡激活兑换比例依旧维持在101的情况,而且后期最划算获得元贝的方式下线(购买文创套装),造成这次雨水酿酒竞赛竞争并不活跃,以至三国志战略版白板关羽可以玩,暴力法关枪,输出控制一体花席之前介绍过法关枪玩法,有粉丝觉得太红了,实际上这个队伍白板也能玩,这一期文章展示一下白板的效果。队伍很简单,就是让SP诸葛亮给关羽法正增加发动概率,但是靠关羽的输出,有时候不太路透社以拜登政府75亿美元撑腰特斯拉向竞争对手开放所有充电站中国小康网02月16日讯老马作为75亿美元联邦计划的一部分,特斯拉公司(TSLA。O)将向竞争对手制造的电动汽车(EV)开放其美国部分充电网络,该计划旨在扩大电动汽车的使用并减少碳日本政府针对电池工厂投资将补贴13不分国内外企业出品搜狐汽车2月20日,据外媒报道,日本根据经济安全保障推进法,最近确定了对蓄电池投资的支持措施。据悉,日本将补贴电池工厂设备投资的13,并有助于在生产时减排二氧化碳技术研发。此举亨利近三十年最佳前锋,除了罗纳尔多我只认可1人,我还不够格亨利认为,足坛近三十年涌现出不少出色的前锋,不过真正能得到我认可的,除了大罗之外就只有1人,舍普琴科,他在米兰时,几乎赢得了所有荣誉,他的名气和实力都是我望尘莫及的,在当时意甲乃至我国空间新技术试验卫星第二批科学与技术成果发布我国空间新技术试验卫星第二批科学与技术成果发布记者从中科院微小卫星创新研究院获悉,我国创新X系列首发星空间新技术试验卫星第二批科学与技术成果近日发布。这批成果主要包括获得我国首幅太京张高铁,中国第一条智能高铁,技术很先进,但既慢又贵,苦了通勤族导语京张高铁,即北京北站至张家口站的高速铁路,营业里程约167公里,最高设计时速350公里,是北京至西北地区的快速通道和京津冀一体化协同发展的重要交通设施,是中国第一条智能化高铁,中国女排变阵?袁心玥王媛媛非唯一选择,双塔组合有多种版本可选面对今年繁重的国际赛事,中国女排的姑娘们结束了军训之后迅速展开集训,体能与技战术训练都不能放松,两手都要抓。为了激发队员们的潜能并加强队伍的一传防守拦网与进攻质量,蔡斌有意调整战术本土首次检出XBB。1。5,会引发新一轮感染高峰吗?我国在前段时间已经有较多人群被感染,形成了一定的群体免疫,所以目前不太可能引起新一波的流行,短期内也没有迹象表明XBB。1。5会在我国引起大规模传播。广州医科大学附属市八医院感染病