Golang channle(管道)基本介绍、快速入门

channel(管道)-基本介绍


为什么需要channel?前面使用全局变量加锁同步来解决goroutine的通讯,但不完美

1)主线程在等待所有goroutine全部完成的时间很难确定,我们这里设置10秒,仅仅是估算。
2)如果主线程休眠时间长了,会加长等待时间,如果等待时间短了,可能还有goroutine处于工作状态,这时也会随主线程的退出而销毁
3)通过全局变量加锁同步来实现通讯,也并不利用多个协程对全局变量的读写操作。
4)上面种种分析都在呼唤一个新的通讯机制-channel

package main

import (
	"fmt"
	"sync"
	"time"
)

var (
	m = make(map[int]int, 10)
	//声明一个全局的互斥锁  lock是一个全局的互斥锁
	//sync是包 同步的意思 mutex是互斥的意思
	lock sync.Mutex
)

// test函数就是计算n的阶乘
func test(n int) {
	res := 1
	for i := 1; i <= n; i++ {
		res = res * i
	}
	//将计算结果放到map当中 加锁
	lock.Lock()
	m[n] = res
	lock.Unlock()
}

func main() {
	//这里开启多协程完成任务
	for i := 1; i <= 20; i++ {
		go test(i)
	}

	time.Sleep(time.Second * 10)
	for k, v := range m {
		fmt.Println(k, v)
	}
}


 

 

channel的介绍


1)channle本质就是一个数据结构-队列【示意图】
2)数据是先进先出
3)线程安全,多goroutine访问时,不需要加锁,就是说channel本身就是线程安全的(管道是线程安全的,你在对管道读取的时候不管有多少个协程在对同一个管道操作,可以放心使用,不会出现错误,这些是有编译器在底层维护的)
4)channel时有类型的,一个string的channel只能存放string类型数据。(如果管道想放int或者float那么可以使用空接口interface类型)
 

 

 

定义/声明channel


var变量名chan敞据类型

举例:

var intChan chan int (intChan用于存放int数据)
var mapChan chan map[int]string  (mapChan用于存放map[int]string类型)
var perChan chan Person
var perChan2 chan *Person

说明:

1)channel是引用类型

2)channel必须初始化才能写入数据,即make后才能使用

3)管道是有类型的,intChan只能写入整数int

channel初始化


说明:使用make进行初始化

var intChan chan int
intChan =make(chan int,10)

向channel中写入(存放)数据

var intChan chan int
intChan =make(chan int,10)
num =999
intChan<-10
intChan<-num

如果将channel传给另外一个函数,那么在这个函数里面操作的是同一个管道,因为它是引用类型。

package main

import "fmt"

func main() {
	var intChan chan int
	//创建可以存放3个int类型的管道
	intChan = make(chan int, 3)

	//看看intChan是什么
	fmt.Printf("initChan的值为=%v\ninitChan本身地址为%p\n", intChan, &intChan)

	//向管道写入数据
	intChan <- 1
	num := 2
	intChan <- num
	//当给管道写入数据的时候,不能超过其容量
	//看看管道的长度和cap
	fmt.Println("长度:", len(intChan), "容量:", cap(intChan))

	num1 := <-intChan
	fmt.Println("取出来的第一个数据是:", num1)
	fmt.Println("取出之后的长度:", len(intChan), "取出之后的容量:", cap(intChan))

	//在没有使用协程的情况下,如果我们的管道数据已经全部取出,再取就会报告deadlock
}


initChan的值为=0xc00007a080
initChan本身地址为0xc00000a028
长度: 2 容量: 3                    
取出来的第一个数据是: 1            
取出之后的长度: 1 取出之后的容量: 3

相关推荐

  1. 快速入门Kotlin①基本语法

    2023-12-07 09:26:02       38 阅读
  2. Linux Shell 管道基本介绍

    2023-12-07 09:26:02       44 阅读
  3. [Rust] 快速基础入门教程

    2023-12-07 09:26:02       43 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-07 09:26:02       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-07 09:26:02       106 阅读
  3. 在Django里面运行非项目文件

    2023-12-07 09:26:02       87 阅读
  4. Python语言-面向对象

    2023-12-07 09:26:02       96 阅读

热门阅读

  1. vue2框架简易版响应式设计(观察者模式)

    2023-12-07 09:26:02       58 阅读
  2. libevent库中的http相关函数举例

    2023-12-07 09:26:02       53 阅读
  3. 如何设置不同的网页标题(react)

    2023-12-07 09:26:02       55 阅读
  4. mvn site 命令

    2023-12-07 09:26:02       58 阅读
  5. L0、Linux常用命令

    2023-12-07 09:26:02       59 阅读
  6. 【LeeCode】350.两个数组的交集 II

    2023-12-07 09:26:02       55 阅读
  7. ElasticSearch之Index stats API

    2023-12-07 09:26:02       55 阅读
  8. 后端返回数据前端保留两位小数

    2023-12-07 09:26:02       62 阅读
  9. 【算法集训】基础数据结构:二、字符串

    2023-12-07 09:26:02       64 阅读
  10. C语言——二级指针

    2023-12-07 09:26:02       59 阅读
  11. docker:安装nginx并部署一个前端项目

    2023-12-07 09:26:02       52 阅读
  12. LeetCode //C - 383. Ransom Note

    2023-12-07 09:26:02       60 阅读