兄弟连Go语言培训清华尹成带你实战GO案例(1) Go 状态协程

XDLGo · 2018-07-31 08:44:43 · 778 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2018-07-31 08:44:43 的主题,其中的信息可能已经有所发展或是发生改变。

  兄弟连GO语言培训课程体系设计架构包括了区块链的基础语言Go语言、区块链后端技术体系、区块链公链、区块链分布式应用开发等内容讲解,以及到最后的面试指导和项目实战。课程由清华微软谷歌名师团队精心打造,历时半年时间共同研发而出。

  Go状态协程

  在上面的例子中,我们演示了如何通过使用mutex来在多个协程之间共享状态。另外一种方法是使用协程

  内置的同步机制来实现。这种基于通道的方法和Go的通过消息共享内存,保证每份数据为单独的协程所有

  的理念是一致的。

  packagemain

  import(

  "fmt"

  "math/rand"

  "sync/atomic"

  "time"

  )

  //在这个例子中,将有一个单独的协程拥有这个状态。这样可以

  //保证这个数据不会被并行访问所破坏。为了读写这个状态,其

  //他的协程将向这个协程发送信息并且相应地接受返回信息。

  //这些readOpwriteOp结构体封装了这些请求和回复

  typereadOpstruct{

  keyint

  respchanint

  }

  typewriteOpstruct{

  keyint

  valint

  respchanbool

  }

  funcmain(){

  //我们将计算我们执行了多少次操作

  varopsint64=0

  //reads和writes通道将被其他协程用来从中读取或写入数据

  reads:=make(chan*readOp)

  writes:=make(chan*writeOp)

  //这个是拥有state的协程,state是一个协程的私有map

  //变量。这个协程不断地select通道readswrites

  //当有请求来临的时候进行回复。一旦有请求,首先执行所

  //请求的操作,然后给resp通道发送一个表示请求成功的值。

  gofunc(){

  gofunc(){

  varstate=make(map[int]int)

  for{

  select{

  caseread:=<-reads:

  read.resp<-state[read.key]

  casewrite:=<-writes:

  state[write.key]=write.val

  write.resp<-true

  }

  }

  }()

  //这里启动了100个协程来向拥有状态的协程请求读数据。

  //每次读操作都需要创建一个readOp,然后发送到reads

  //通道,然后等待接收请求回复

  forr:=0;r<100;r++{

  gofunc(){

  for{

  read:=&readOp{

  key:rand.Intn(5),

  resp:make(chanint)}

  reads<-read

  <-read.resp

  atomic.AddInt64(&ops,1)

  }

  }()

  }

  //我们开启10个写协程

  forw:=0;w<10;w++{

  gofunc(){

  for{

  write:=&writeOp{

  key:rand.Intn(5),

  val:rand.Intn(100),

  resp:make(chanbool)}

  writes<-write

  <-write.resp

  atomic.AddInt64(&ops,1)

  }

  }()

  }

  //让协程运行1秒钟

  time.Sleep(time.Second)

  //最后输出操作数量ops的值

  opsFinal:=atomic.LoadInt64(&ops)

  fmt.Println("ops:",opsFinal)

  }

  运行结果

  ops:880578

  运行这个程序,我们会看到基于协程的状态管理每秒可以处理800,000个操作。对于这个例子来讲,基于

  协程的方法比基于mutex的方法更加复杂一点。当然在某些情况下还是很有用的。例如你有很多复杂的协

  程,而且管理多个mutex可能导致错误。

  当然你可以选择使用任意一种方法,只要你保证这种方法让你觉得很舒服而且也能保证程序的正确性。


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

778 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传