0%

协程---channel 练习

1. 用协程实现顺序打印123

func main() {
	ch := make(chan int)
	for i := 1; i <= 3; i++ {
		go func() {
			fmt.Println(<-ch)
		}()
		ch <- i
		time.Sleep(time.Second)
	}

}

2. 用Channel和两个协程实现数组相加

//用Channel和两个协程实现数组相加
func main() {
	num1 := [3]int{1, 2, 3}
	num2 := [3]int{1, 2, 3}
	res := make([]int, 3)
	ch1 := make(chan int)
	ch2 := make(chan int)
	sum := make(chan struct{})
	go func() {
		for i := 0; i < 3; i++ {
			<-sum
			ch1 <- num1[i]
			ch2 <- num2[i]

		}
	}()

	go func() {
		for i := 0; i < 3; i++ {
			tem := <-ch1 + <-ch2
			res[i] = tem
			fmt.Println("+", tem)

		}
	}()
	for i := 0; i < 3; i++ {
		sum <- struct{}{}
		time.Sleep(time.Second)
	}
	fmt.Println(res)
}

all goroutines are asleep - deadlock-Go中协程死锁详解

channel 程序写的不对很容易发生死锁

这究竟是咋回事呢?
首先我们这里通过make(chan int),开辟的通道是一种无缓冲通道,所以当对这个缓冲通道写的时候,会一直阻塞等到某个协程对这个缓冲通道读(大家发现没有这个与典型的生产者消费者有点不一样,当队列中“内容”已经满了,生产者再生往里放东西才会阻塞,而这里我讲ch<- 理解为生产,他却是需要等到某个协程读了再能继续运行)。
main函数的执行在go语言中本身就是一个协程的执行,所以在执行到c<-‘A’的时候,执行main函数的协程将被阻塞,换句话说main函数被阻塞了,此时不能在继续往下执行了,所以整个程序阻塞,发生了死锁。

3. 数字字母交替打印

//用GO写数字字母交替打印的协程,要求使用两个协程分别打印
func main() {
   ch := make(chan int)
   //ch2 := make(chan int)
   tem := make(chan struct{})
   go func() {
      for i := 1; i <= 10; i++ {
         <-tem
         fmt.Print(i)
         ch <- i
      }
   }()
   go func() {
      c := 'A'
      for i := 0; i < 10; i++ {
         <-ch
         fmt.Printf("%c", c)
         c++
      }
   }()
   for i := 0; i < 10; i++ {
      tem <- struct{}{}
      time.Sleep(time.Second)
   }
}
-------------本文结束感谢您的阅读-------------
打赏一瓶矿泉水