go并发的几个例子

发布时间 2023-10-08 11:01:35作者: 坚强的小蚂蚁

参考:cnblogs.com/aaronthon/p/10946433.html

例子1
package main

import "fmt"

func main() {
	ch := make(chan int, 5)

	ch <- 1
	ch <- 2
	ch <- 4
	ch <- 10
	close(ch)

	for v := range ch {
		fmt.Println(v)
	}

	//fmt.Println(<-ch)
	//fmt.Println(<-ch)
	//fmt.Println(<-ch)
	//fmt.Println(<-ch)

}

例子2
package main

import (
	"fmt"
	"time"
)

func sendData(ch chan int) {
	for i := 0; i < 5; i++ {
		ch <- i
		time.Sleep(time.Second)
	}
	close(ch)
}

func main() {
	ch := make(chan int)
	go sendData(ch)
	for v := range ch {
		fmt.Println(v)
	}
}

例子3
package main

import "fmt"

func main() {
	ch1 := make(chan int)
	ch2 := make(chan int)
	// 开启goroutine将0~100的数发送到ch1中
	go func() {
		for i := 0; i < 100; i++ {
			ch1 <- i
		}
		close(ch1)
	}()
	// 开启goroutine从ch1中接收值,并将该值的平方发送到ch2中
	go func() {
		for {
			i, ok := <-ch1
			if !ok {
				break
			}
			ch2 <- i * i
		}
		close(ch2)
	}()
	// 在主goroutine中从ch2中接收值打印
	for i := range ch2 {
		fmt.Println(i)
	}

}

从上面的例子中我们看到在接收值的时候,判断通道是否被关闭有两种方式,我们通常使用的是for range的方式。

例子4
package main

import "fmt"

func counter(out chan<- int) {
	for i := 0; i < 100; i++ {
		out <- i
	}
	close(out)
}

func squarer(out chan<- int, in <-chan int) {
	for i := range in {
		out <- i * i
	}
	close(out)
}

func printer(in <-chan int) {
	for i := range in {
		fmt.Println(i)
	}
}

func main() {
	ch1 := make(chan int)
	ch2 := make(chan int)
	go counter(ch1)
	go squarer(ch2, ch1)
	printer(ch2)
}

其中,chan<- int是一个只能发送的通道,可以发送但是不能接收;<-chan int是一个只能接收的通道,可以接收但是不能发送。在函数传参及任何赋值操作中将双向通道转换为单向通道是可以的,但反过来是不可以的。