zoukankan      html  css  js  c++  java
  • goroutine(2) goroutine同步

    1.查看cpu和设置

    package main
    import (
    	"fmt"
    	"runtime"
    )
    func main(){
    	 n := runtime.NumCPU() //查看物理机cpu数量
    	 runtime.GOMAXPROCS(n) //设置使用多少cpu,也就是多少个p
    	 fmt.Println(n)       //4
    }
    

    2.不同goroutine之间如何进行同步

    出现问题场景:出现问题场景: 一个函数run()中包含多个goroutine函数并发,这些goroutine函数会生成中间文件, 被run()函数运行结束后的check()函数检查. 当goroutine并发时, 并不会阻塞run()的上下文, 可能导致的情况为run()函数执行完毕( 但其中的goroutine并发函数没有执行完毕 ), 导致check()函数执行失败.

    所以我们需要一种操作, 直到当前所有goroutine执行完毕, 才进行下一步操作,所以需要 goroutine同步

    1)全局变量和锁同步

    package main
    
    import(
    	"fmt"
    	"time"
    )
    func calc() {
    	for i := 0; i < 1000; i++ {
    		time.Sleep(time.Millisecond)
    	}
    }
    func main() {
    	start := time.Now().UnixNano()
    	go calc()
    	go calc()
    	go calc()
    	end := time.Now().UnixNano()
    	fmt.Printf("finished, cost:%d ms
    ", (end - start)/1000/1000) // finished,cost:0 ms
    }
    

      上面的例子品输出的是0ms,因为每个goroutine并没有阻塞主函数main()的运行,主函数结束了,而其它goroutine可能还在运行,看下面的改变,利用全局变量来等待所有的goroutine执行完成

    package main
    
    import(
    	"fmt"
    	"time"
    )
    var iscomp [3]bool   //设置全局变量
    func calc(index int) {
    	for i := 0; i < 1000; i++ {
    		time.Sleep(time.Millisecond)
    	}
    	iscomp[index] = true
    	
    }
    func main() {
    	start := time.Now().UnixNano()
    	go calc(0)    //每启用一个,就改变量的值
    	go calc(1)
    	go calc(2)
    	for {        //死循环 等待所有的goroutine执行完成
    		if iscomp[0] && iscomp[1] && iscomp[2] {
    			break
    		}
    		time.Sleep(time.Millisecond)
    	}
    	end := time.Now().UnixNano()
    	fmt.Printf("finished, cost:%d ms
    ", (end - start)/1000/1000) //finished, cost:1080 ms
    }
    

      go语言里提供了一个sync包来等待所有的goroutine执行完成,

    package main
    
    import(
    	"fmt"
    	"time"
    	"sync"
    )
    // var iscomp [3]bool   //设置全局变量
    func calc(waitgroup *sync.WaitGroup) {
    	for i := 0; i < 1000; i++ {
    		time.Sleep(time.Millisecond)
    	}
    	waitgroup.Done()
    	// iscomp[index] = true
    	
    }
    func main() {
    	var waitgroup sync.WaitGroup      //申明一个变量
    	start := time.Now().UnixNano()
    	waitgroup.Add(3)
    	go calc(&waitgroup)
    	go calc(&waitgroup)
    	go calc(&waitgroup)
    	               //每启用一个,增加一个,或者改成以下代码:
    	
    	/*
    	for i:= 0;i<3;i++{
    		waitgroup.Add(1)
    		go calc(&waitgroup)
    	}
    	*/
    	// for {        //死循环 等待所有的goroutine执行完成
    	// 	if iscomp[0] && iscomp[1] && iscomp[2] {
    	// 		break
    	// 	}
    	// 	time.Sleep(time.Millisecond)
    	// }
    	waitgroup.Wait()
    	end := time.Now().UnixNano()
    	fmt.Printf("finished, cost:%d ms
    ", (end - start)/1000/1000) //finished, cost:1080 ms
    }
    

      

    2)channel(看下一篇channel)

  • 相关阅读:
    zhuan:Jmeter基础之---jmeter基础概念
    zhuan:JMeter基础之--元件的作用域与执行顺序
    zhuan:JMeter基础之—录制脚本
    zhuan:一种简单的数据库性能测试方法
    转:使用JMeter创建FTP测试计划
    转:JMeter基础之一 一个简单的性能测试
    性能学习
    [转]JMeter学习(一)工具简单介绍
    后端文件接收resd()和chunk的区别
    PyQt环境安装
  • 原文地址:https://www.cnblogs.com/wanghaijun999/p/8352278.html
Copyright © 2011-2022 走看看