Go语言快速入门笔记(二):并发编程部分

彩笔梳子 · · 698 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

1.协程是轻量级的线程的理解

(1)java里的Thread默认为1M,Groutine的Stack初始化为2K
(2)一个thread对应一个kernel space,groutine则是多对多

2.第一个简单的多线程案列

   for i := 0; i < 10; i++ {
      go func(i int) {
         println(i)
      }(i)
   }
}

3.如何做到多线程累加同一数据的安全性

func TestGroutine1(t *testing.T)  {
   count := 0
 mutex := sync.Mutex{}
   for i := 0; i < 10; i++ {
      go func() {
         defer func() {
            mutex.Unlock()
         }()
         mutex.Lock()
         count++
         println(count)
      }()
      }
}

4.如何打印完10个数主线程再输出Done?

func TestGroutine1(t *testing.T)  {
   count := 0
 mutex := sync.Mutex{}
   wg := sync.WaitGroup{}
   for i := 0; i < 10; i++ {
      wg.Add(1)
      go func() {
         defer func() {
            mutex.Unlock()
         }()
         mutex.Lock()
         count++
         println(count)
         wg.Done()
      }()
   }
   wg.Wait()
   println("done")
}

5.CSP并发机制

结合一个前端开发的场景,使用ajax异步去数据
会阻塞在取数据的channel上
func AsyncAJAX() chan string {
   channel := make(chan string)
   data := "Hello world"
 go func() {
      time.Sleep(time.Second * 10)
      println("ajax执行完毕")
      channel <- data
 }()
   return channel
}
func TestCSP(t *testing.T)  {
   println("Ajax发送请求")
   c := AsyncAJAX()
   println("渲染")
   println("取数据",<-c)
}

6.select多路选择做超时控制

func TestCSP(t *testing.T)  {
   println("Ajax发送请求")
   c := AsyncAJAX()
   select {
   case ret := <-c:
      t.Log(ret)
   case <- time.After(time.Second * 5):
      t.Log("time out")
   }
}

7.close掉channel会迅速接到0值

8.带buffer的话就可以堆积

func dataSend(c chan int)  {
   go func() {
      for i := 0;;i++ {
         time.Sleep(time.Second * 1)
         println("发送第", i)
         c <- i
 }}()
}
func dataRecv(c chan int)  {
   go func() {
      for {
         time.Sleep(time.Second * 5)
         println("接收第", <- c)
      }}()
}
func TestMore(t *testing.T)  {
   c := make(chan int, 5)
   dataSend(c)
   dataRecv(c)
   time.Sleep(time.Second * 100)
}

9.任意一个任务完成

func anyComplete() int {
   channel := make(chan int)
   for i := 0; i < 10; i++ {
      go func(i int) {
         time.Sleep(time.Duration(rand.Int31n(10)))
         channel <- i
 }(i)
   }
   return <-channel
}
func TestAnyComplete(t *testing.T)  {
   t.Log("result is from ", anyComplete())
}

10.所有任务都执行完成

func TestAllComplete(t *testing.T)  {
   channel := make(chan int)
   for i := 0; i < 10; i++ {
      go func(i int) {
         time.Sleep(time.Duration(rand.Int31n(10)))
         channel <- i
 }(i)
   }
   sum := 0
 for i := 0; i < 10; i++ {
      sum += <- channel
 }
   println(sum)
}

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

本文来自:Segmentfault

感谢作者:彩笔梳子

查看原文:Go语言快速入门笔记(二):并发编程部分

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

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