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\n", (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\n", (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\n", (end - start)/1000/1000) //finished, cost:1080 ms
}

  

 

2)channel(看下一篇channel)

posted @ 2018-01-25 17:25  whj999  阅读(140)  评论(0编辑  收藏  举报