Golang并发编程之goroutine

0、Go语言中的并发编程

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

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

1、goroutine简介

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

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

2、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

}

3、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()
}
posted @ 2020-02-23 01:09  jasonminghao  阅读(236)  评论(0编辑  收藏  举报