Golang中的管道

本文探讨了Go语言中的channel(通道)及其在并发编程中的关键作用,包括整数管道的创建、操作和关闭,以及如何通过协程实现主线程与子任务间的高效通信。此外,还涉及了管道在数据流控制和多线程协作中的实际应用场景。
摘要由CSDN通过智能技术生成

类似Queue

package main

import "fmt"

func main() {
	var intChannel chan int

	intChannel = make(chan int, 3)

	fmt.Printf("intChannel:%v\n", intChannel)
	fmt.Printf("&intChannel:%p\n", &intChannel)

	// 向管道写入数据
	intChannel <- 10
	num := 100
	intChannel <- num

	intChannel <- 50
	// 向管道写入数据时,不能超过其容量
	//intChannel <- 98

	fmt.Printf("length:%v, capacity:%v\n", len(intChannel), cap(intChannel)) // length:3, capacity:3

	var num1 int
	// 从管道读取数据
	num1 = <-intChannel
	fmt.Println(num1) // 10

	fmt.Printf("length:%v, capacity:%v\n", len(intChannel), cap(intChannel)) // length:2, capacity:3

	intChannel <- 98
	fmt.Printf("length:%v, capacity:%v\n", len(intChannel), cap(intChannel)) // length:3, capacity:3

	num1 = <-intChannel
	fmt.Println(num1) // 100

	// 取出,不接收
	<-intChannel
	fmt.Printf("length:%v, capacity:%v\n", len(intChannel), cap(intChannel)) // length:1, capacity:3
}

管道的关闭与遍历


func main() {
	intChannel := make(chan int, 3)
	intChannel <- 100
	intChannel <- 200
	// 关闭管道,关闭后不能写入,可以读取
	//close(intChannel)
	num := <-intChannel
	fmt.Println("num:", num) // 100

	intChannel <- 300
	num = <-intChannel
	fmt.Println("num:", num) // 200

	intChannel <- 400
	intChannel <- 500

	// channel未关闭时遍历会出现deadlock错误,关闭后可以遍历
	close(intChannel)
	// 不能使用for循环来遍历
	for value := range intChannel {
		fmt.Println(value)
		//300
		//400
		//500
	}
}

主线程与协程 管道通信

package main

import (
	"fmt"
	"time"
)

func writeData(intChannel chan int) {
	for i := 0; i < 10; i++ {
        // 如果已经满了 会阻塞
		intChannel <- i
		fmt.Println("写入数据:", i)
		time.Sleep(time.Second)
	}
	close(intChannel)
}

func readData(intChannel chan int, exitChannel chan bool) {
	for {
		// 从intChannel读取,没有数据则阻塞
		v, ok := <-intChannel
		if !ok {
			break
		}
		fmt.Println("读取数据:", v)
		time.Sleep(time.Second)
	}
	exitChannel <- true
	close(exitChannel)
}

func main() {
	intChannel := make(chan int, 10)
	exitChannel := make(chan bool, 1)

	fmt.Println("开始写")
	go writeData(intChannel)

	fmt.Println("开始读")
	go readData(intChannel, exitChannel)

	fmt.Println("主线程开始检查是否读取完成")
	for {
		// 从exitChannel中读取退出标志,如果没有标志则阻塞
		_, ok := <-exitChannel
		fmt.Println("主线程检查是否读取完成:", ok)
		if ok {
			break
		}
	}
}
开始写
开始读
主线程开始检查是否读取完成
读取数据: 0
写入数据: 0
读取数据: 1
写入数据: 1
写入数据: 2
读取数据: 2
写入数据: 3
读取数据: 3
写入数据: 4
读取数据: 4
写入数据: 5
读取数据: 5
写入数据: 6
读取数据: 6
写入数据: 7
读取数据: 7
写入数据: 8
读取数据: 8
写入数据: 9
读取数据: 9
主线程检查是否读取完成: true

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值