关于无缓冲管道(容量为0的管道)

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