package main import ( "fmt" "time" ) func main() { chanInt := make(chan int) // 出于演示需要这里使用int,实际开发中强烈建议使用struct{}以提高性能 go func() { fmt.Println("(1)、生产者:即将向管道写入数据") chanInt <- 1024 fmt.Println("(4)、生产者:向管道写入数据成功") }() time.Sleep(time.Second * 5) fmt.Println("(2)、消费者:即将从管道取出数据") val := <-chanInt fmt.Printf("(3)、消费者:从管道取出数据(%d)成功\n", val) time.Sleep(time.Second) fmt.Println("(5)、程序结束") } // 输出结果: // -------------------------------------------------- // (1)、生产者:即将向管道写入数据 // (2)、消费者:即将从管道取出数据 // (3)、消费者:从管道取出数据(1024)成功 // (4)、生产者:向管道写入数据成功 // (5)、程序结束 // ========== 说明 ========== // // 1、创建管道时缺省容量参数或者容量参数设置为0,就是0容量管道,也叫无缓冲管道。 // 2、无缓冲管道因为容量为0,所以不能暂存数据。由于不需要使用内存来存储数据,双方之间通信也更高效和低延迟。 // 3、使用无缓冲管道可能会阻塞生产者或消费者: // 当生产者向管道写入数据时没有消费者准备好接收数据,那么写入操作就会被阻塞,直到有消费者接收数据; // 当消费者从管道接收数据时没有生产者准备好写入数据,那么接收操作就会被阻塞,直到有生产者写入数据。 // 因为上述两个特点,无缓冲管道特别适用于需要严格同步的场景,例如有ABC三个任务必须要按顺序依次执行, // 那么就可以使用接收数据操作先把任务B和任务C阻塞,然后执行任务A,任务A执行完后写入数据解除任务B的阻塞, // 任务B执行完后写入数据解除任务C的阻塞,以此达到让多任务严格按顺序执行的效果。 // 4、由于使用无缓冲管道很多场景只是传递信号,并不关心数据类型和值,所以建议使用空结构体管道,而不是int管道或其它管道。
Copyright © 2024 码农人生. All Rights Reserved