zoukankan      html  css  js  c++  java
  • 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
    ",i)
    	}
    }
    
    func b(){
    	defer wg.Done()
    	for i:=0;i<10;i++{
    		fmt.Printf("B:%d
    ",i)
    	}
    }
    
    func main(){
    	runtime.GOMAXPROCS(1) // 指定在N个核心数上调度
    	wg.Add(2)
    	go a()
    	go b()
    	wg.Wait()
    }
    
  • 相关阅读:
    Toolbar设置回退箭头的方法
    Android进程绝杀技--forceStop
    线程池的经典使用
    Handler+ExecutorService(线程池)+MessageQueue模式+缓存模式
    adb pull apk
    工厂模式_工厂方法模式
    工厂模式_简单工厂模式
    spring_aop
    代理模式_动态代理
    代理模式_静态代理
  • 原文地址:https://www.cnblogs.com/jasonminghao/p/12348277.html
Copyright © 2011-2022 走看看