golang中并发实例

package main

import (
	"fmt"
	//"runtime"
	"os"
	"runtime/pprof" // 引用pprof package
	"time"
)

func main() {
	f, _ := os.Create("profile_file")
	pprof.StartCPUProfile(f)     // 开始cpu profile,结果写到文件f中
	defer pprof.StopCPUProfile() // 结束profile

	startTime := time.Now().Second()
	//runtime.GOMAXPROCS(runtime.NumCPU())

	// 注意这里的缓存大小
	ch := make(chan int, 100)
	quit := make(chan bool)

	// 注意这里把读取chan操作放在了写入chan之前了(为了安全建议对chan的goroutines读取放在前面,写入放在后面)
	// 如果把这行放在了for逻辑后面,则上面声明的chan缓冲区大小一定要大于2000才可以,否则由
	// 于缓存区一次放不下2000个元素,从而产生deadlock
	go read(ch, quit)

	for i := 0; i < 2000; i++ {
		ch <- i
		fmt.Println(i)
	}

	quit <- true

	fmt.Println("\r\n====MAIN END====")
	endTime := time.Now().Second()

	fmt.Println(startTime)
	fmt.Println(endTime)
	fmt.Println("用时:", endTime-startTime, "秒")
}

func read(ch chan int, quit chan bool) {
	for {
		select {
		case value := <-ch:
			fmt.Print("----", value, "----")
		case <-quit:
			break
		}

	}
}

channel总结:
channel共分两种:一种是有buffer的,一种是没有buffer的,默认是没有buffer的,即buffer长度为0

c := make(chan int) //无buffer
c := make(chan int, 0) //无buffer

c := make(chan int, 100) //有buffer
  • 有缓冲的channel,且写入chan个数>=缓存区大小时,可以先“”后“读”,否则反之
  • 无缓冲的channel,要先“”后“写”

注意本例中运行在goroutines中的为操作
推荐:如何优雅地关闭Go channel