面试题 / Golang

channel

这块我实际用的 真的特别少(一次都没有)..

所以自己学习再练习一下

有缓冲

有缓冲的,当写操作满了,读操作还没开始的话,也是会发生阻塞的

如果主程不结束,信道没写读完,也是会阻塞在那的!

c := make(chan int, 50)
	go func() {
		for i:=0;i<40;i++ {
			fmt.Println("received---------", i)
			x := <-c
			fmt.Println("received", x)
		}
		fmt.Println("能走到这么")
	}()
	time.Sleep(2*time.Second)
	for i:=0;i<10;i++ {
		c <- i
		fmt.Println("sending", i)
	}
	for  {
		
	}

如果写比读的多.. 会报错,说 所有线程都sleep

如果读比写多.. 读那块会阻塞! 没写完没有关系

如果读和写都比总数多.. 只有有读有写,就没事

如果读和写都比总数小.. 也没啥影响..

done := make(chan bool)

	doSort := func(s []int) {
		sort.Ints(s)
		fmt.Println(s)
		done <- true
	}
	s := []int{3,4,2,1,5,6,9,7,0,8}
	i := len(s) >> 1
	go doSort(s[:i])
	go doSort(s[i:])
	<-done
	<-done

主程阻塞住,然后协程里写入数据,这时候主程才能继续走!

如果 用 range 去输出数据,写的有问题的话没有close的话,会报错,“fatal error: all goroutines are asleep - deadlock!” 所以正常range 最好是close!这样比较正常

无缓冲

比如:

    ch := make(chan int) //创建一个无缓冲channel
    fmt.Println(2342)
    ch<-2
    fmt.Println(234444444)
    a := <-ch
    fmt.Println(a)

无缓冲的时候,这种串行读写的话,都会发生阻塞,

2342
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan send]:
main.main()
	F:/workspaces/interview/ttest.go:31 +0xd5

Process finished with exit code 2

可以考虑这样写

    ch := make(chan int) //创建一个无缓冲channel
	fmt.Println(2342)
	go func() {
		ch<-2
	}()

	fmt.Println(234444444)
	go func() {
		a := <-ch
		fmt.Println(a)
	}()

放入两个协程里(一个也可以的),两个并发阻塞,一个开始写,一个准备读!