• Go语言中的有缓冲channel和无缓冲channel区别


    Go语言中的有缓冲channel和无缓冲channel区别

    结论

    ch1:=make(chan int)// 无缓冲
    
    ch2:=make(chan int,1)// 有缓冲
    

    无缓冲: 当向ch1中存值后需要其他协程取值,否则一直阻塞

    有缓冲: 不会阻塞,因为缓冲大小是1,只有当放第二个值的时候,第一个还没被人拿走,才会阻塞。

    测试程序

    测试1,声明无缓冲channel

    func Test_1(t *testing.T) {
    	// 无缓冲
    	ch := make(chan int)
    	// fatal error: all goroutines are asleep - deadlock! 协程阻塞,需要另一个协程取走channel中的值
    	ch <- 1
    }
    

    运行结果:

    === RUN   Test_1
    fatal error: all goroutines are asleep - deadlock!
    
    goroutine 1 [chan receive]:
    testing.(*T).Run(0xc0000c0100, 0x55bb8e, 0x6, 0x566b20, 0x47e55d)
    	D:/Go/src/testing/testing.go:961 +0x37e
    testing.runTests.func1(0xc0000c0000)
    	D:/Go/src/testing/testing.go:1202 +0x7f
    testing.tRunner(0xc0000c0000, 0xc00008fdc0)
    	D:/Go/src/testing/testing.go:909 +0xd0
    testing.runTests(0xc000060460, 0x654300, 0x4, 0x4, 0x0)
    	D:/Go/src/testing/testing.go:1200 +0x2ae
    testing.(*M).Run(0xc0000b6000, 0x0)
    	D:/Go/src/testing/testing.go:1117 +0x17d
    main.main()
    	_testmain.go:50 +0x13c
    
    goroutine 19 [chan send]:
    test/review.Test_1(0xc0000c0100)
    	E:/Go/src/test/review/main_test.go:64 +0x57
    testing.tRunner(0xc0000c0100, 0x566b20)
    	D:/Go/src/testing/testing.go:909 +0xd0
    created by testing.(*T).Run
    	D:/Go/src/testing/testing.go:960 +0x357
    
    Process finished with exit code 1
    
    

    测试2,开启协程取值

    func Test_2(t *testing.T) {
    	// 无缓冲
    	ch := make(chan int)
    	go func() {
    		// 睡眠1秒,等待主协程在channel写入值
    		time.Sleep(time.Second * 1)
    		fmt.Println("开始取值。。。")
    		<-ch
    	}()
    	fmt.Println("开始存值。。。")
    	ch <- 1
    	time.Sleep(time.Second*5)
    	fmt.Println("结束。。。")
    }
    

    运行结果:

    === RUN   Test_2
    开始存值。。。
    开始取值。。。
    结束。。。
    --- PASS: Test_2 (6.00s)
    PASS
    
    Process finished with exit code 0
    

    测试3,声明有缓冲channel

    func Test_3(t *testing.T) {
    	// 有缓冲
    	ch1 := make(chan int, 1)
    	// 缓冲大小为1  即是当channel中有一个值时不会被阻塞,当再塞入一个时前一个没被其他协程取走才会阻塞
    	ch1 <- 2
    	// 此时主协程也可取出值
    	fmt.Println(<-ch1)
    }
    

    运行结果:

    === RUN   Test_3
    2
    --- PASS: Test_3 (0.00s)
    PASS
    
    Process finished with exit code 0
    

    测试4,存入超过缓冲数量的值

    func Test_4(t *testing.T) {
    	// 有缓冲
    	ch1 := make(chan int, 1)
    	// 缓冲大小为1  即是当channel中有一个值时不会被阻塞,当再塞入一个时前一个没被其他携程取走才会阻塞
    	ch1 <- 1
    	// fatal error: all goroutines are asleep - deadlock!
    	ch1 <- 2
    }
    

    测试结果:

    === RUN   Test_4
    fatal error: all goroutines are asleep - deadlock!
    
    goroutine 1 [chan receive]:
    testing.(*T).Run(0xc0000a8100, 0x55bba0, 0x6, 0x566b40, 0x47e501)
    	D:/Go/src/testing/testing.go:961 +0x37e
    testing.runTests.func1(0xc0000a8000)
    	D:/Go/src/testing/testing.go:1202 +0x7f
    testing.tRunner(0xc0000a8000, 0xc000081dc0)
    	D:/Go/src/testing/testing.go:909 +0xd0
    testing.runTests(0xc0000044c0, 0x654300, 0x4, 0x4, 0x0)
    	D:/Go/src/testing/testing.go:1200 +0x2ae
    testing.(*M).Run(0xc00009e000, 0x0)
    	D:/Go/src/testing/testing.go:1117 +0x17d
    main.main()
    	_testmain.go:50 +0x13c
    
    goroutine 6 [chan send]:
    test/review.Test_4(0xc0000a8100)
    	E:/Go/src/test/review/main_test.go:97 +0x76
    testing.tRunner(0xc0000a8100, 0x566b40)
    	D:/Go/src/testing/testing.go:909 +0xd0
    created by testing.(*T).Run
    	D:/Go/src/testing/testing.go:960 +0x357
    
    Process finished with exit code 1
    
    
  • 相关阅读:
    Day2-Python爬虫小练 爬取百科词条
    Day1-python轻量级爬虫
    大数据处理课堂测试1
    周记7-28
    周记7-21
    周记7-14
    软件工程课程总结
    进度15
    NABCD
    团队项目成员和题目
  • 原文地址:https://www.cnblogs.com/Kingram/p/13748253.html
Copyright © 2020-2023  润新知