Golang并发编程之goroutine

Go语言中的并发编程

并发:同一时间段内执行多个任务(你在用微信和两个女朋友聊天)
并行:同一时刻执行多个任务(你和你朋友都在用微信和女朋友聊天)
Go语言的并发通过goroutine实现。goroutine￿类似于线程,属于用户态的线程,我们可以根据需要创建成千上万个goroutine并发工作。goroutine是由Go语言的运行时(runtime)调度完成,而线程是由操作系统调度完成

Go 语言还提供channel在多个goroutine间进行通信。goroutinechannel是Go语言继承的CSP并发模式的重要实现基础

goroutine简介

在Java和C++中我们要实现并发编程的时候,必须要自己维护一个线程池,并且需要自己去包装一个又一个的任务,同时还要自己去调度线程执行任务并维护上下文切换。

Go语言编程中你不需要自己去写进程、线程、协程、你的技能包里只有一个技能goroutine,当你需要让某个任务并发执行的时候,你只需要把这个任务包装成一个函数,开启一个goroutine去执行这个函数就可以了。

goroutine应用

Go语言中使用goroutine非常简单,只需要在调用函数的时候在前面加上一个go关键字,就可以为一个函数创建一个goroutine

一个goroutine必须对应一个函数,可以创建多个goroutine去执行同一个函数

package main

import (
    "fmt"
    "time"
)

// goroutine
func hello(i int){
    fmt.Println("hello",i)
}

// 程序启动之后会创建一个主goroutine去执行
func main(){
    for i:=0;i<100;i++ {
        //go hello(i) // 开启一个单独的goroutine去执行hello函数(任务)
        go func(i int){
            fmt.Println(i)
        }(i)
    }
    fmt.Println("main")
    time.Sleep(time.Second)
    // main函数结束了 由main函数启动的goroutine也都结束了
}

在Go语言中实现并发就是这么简单,我们还可以启动多个goroutine。让我们再举一个例子(这里使用sync.WaitGroup来实现goroutine
的同步)

package main

import (
    "fmt"
    "math/rand"
    "sync"
    "time"
)

func f(i int){
    defer wg.Done() // 计数器减1
    time.Sleep(time.Millisecond * time.Duration(rand.Intn(300)))
    fmt.Println(i)
}

var wg sync.WaitGroup

func main(){
    //f()
    for i:=0;i<10;i++{
        wg.Add(1)  // 计数器加1
        go f(i)
    }
    // 如何知道这10个goroutine都结束了
    wg.Wait() // 等待wg的计数器减为0

}

GOMAXPROCS

Go运行时的调度器会使用GOMAXPROCS参数来确定需要使用多少OS线程来同时执行Go代码,默认值是机器上的CPU核心数。

package main

import (
    "fmt"
    "runtime"
    "sync"
)

var wg sync.WaitGroup

func a(){
    defer wg.Done()
    for i:=0;i<10;i++{
        fmt.Printf("A:%d\n",i)
    }
}

func b(){
    defer wg.Done()
    for i:=0;i<10;i++{
        fmt.Printf("B:%d\n",i)
    }
}

func main(){
    runtime.GOMAXPROCS(1) // 指定在N个核心数上调度
    wg.Add(2)
    go a()
    go b()
    wg.Wait()
}

猜你喜欢

转载自www.cnblogs.com/jasonminghao/p/12348277.html