# Go学习-Day9

news/2024/12/21 16:12:01 标签: golang, 学习, log4j

文章目录

    • Channel
      • 声明
      • 存入取出
      • 一个简单的死锁分析

  • 个人博客:CSDN博客

Channel

  • Channel本质是一个队列
  • 多goroutine访问时不需要加锁,Channel天然线程安全
  • channel有类型,只能写入相同类型
  • channel是引用类型
  • channel必须初始化才能写入数据,make分配内存

声明

  • 	var intChan chan int
    	intChan = make(chan int, 3)
    
  • java不是很熟悉,感觉chan有点像java的原子类

存入取出

  • intChan<- xxx //存入
    a := <= intChan//取出
    
  • 管道不会自然增长,不能超过容量,不能从空的管道里取出数据,会上DeadLock

  • 如果想要存储任意类型的管道,可以用空借口

  • var allChan chan interface{}
    
  • 但是,取出的时候注意类型断言

  • close(intChan)
    
  • channel关闭之后就不能再写入了,但是能继续读出

  • 关闭之后能用for-range来遍历,如果不关闭的话会出现死锁

  • 死锁的情况很多,建议多找几篇文章看看,写写实操一下

  • 空的缓冲chan相当于无缓冲的chan,无缓冲的chan需要接收者,传入者,否则就会死锁,注意及时关闭

  • 只向管道内写入,不读取就会deadlock,读得慢没有关系

  • 关键是要给每个管道安排一个发送者,和接收者!!!

一个简单的死锁分析

package main

import (
	"fmt"
	"time"
)

func write(intChan chan int) {
	for i := 0; i < 5; i++ {
		fmt.Println("写入: ", i)
		intChan <- i
		time.Sleep(time.Second)
	}
	//close(intChan)
}

func read(intChan chan int, exitChan chan bool) {
	for {
		val, ok := <-intChan
		if !ok {
			break
		}
		fmt.Println("读到", val)
	}
	exitChan <- true
	close(exitChan)
}
func main() {

	intChan := make(chan int, 20)
	exitChan := make(chan bool, 1)
	go write(intChan)
	go read(intChan, exitChan)

	for {
		_, ok := <-exitChan
		if !ok {
			break
		}
	}
}

  • 输出
写入:  0
读到 0
写入:  1
读到 1
写入:  2
读到 2
写入:  3
读到 3
写入:  4
读到 4
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive]:
main.main()
        E:/JetBrains/GoLandSpace/src/go_code/project01/main/hello.go:36 +0xe8

goroutine 7 [chan receive]:
main.read(0x0?, 0x0?)
        E:/JetBrains/GoLandSpace/src/go_code/project01/main/hello.go:19 +0x99
created by main.main
        E:/JetBrains/GoLandSpace/src/go_code/project01/main/hello.go:33 +0xd9

Process finished with the exit code 2

  • 下面是个人的分析,不一定对,有大佬可以来指正
  • 如果我们不close,channel是可以读的,我们可以边读,边写,并且,读的速度是可以更慢或者更快的,go底层会通过上下文自行判断。
  • 但是这里,我们写的协程,我们关闭channel,在程序运行完之后自行关闭,此时我们读的协程会卡在intChan,等待读入,但是此时还不会报错,因为协程会因为主线程结束而结束。但是后面的exitChan会导致报错
package main

import (
	"fmt"
	"time"
)

func write(intChan chan int) {
	for i := 0; i < 5; i++ {
		fmt.Println("写入: ", i)
		intChan <- i
		time.Sleep(time.Second)
	}
	//close(intChan)
}

func read(intChan chan int, exitChan chan bool) {
	for {
		val, ok := <-intChan
		if !ok {
			break
		}
		fmt.Println("读到", val)
	}
	fmt.Println("到了这里")
	//exitChan <- true
	//close(exitChan)
}
func main() {

	intChan := make(chan int, 20)
	exitChan := make(chan bool, 1)
	go write(intChan)
	go read(intChan, exitChan)

	time.Sleep(time.Second * 10)
	//for {
	//	_, ok := <-exitChan
	//	if !ok {
	//		break
	//	}
	//}
}

  • 这样并没有报错,并且发现到了这里没有打印,说明read函数作为intChan的接收者一直在等待,这时候。

  • 但是,主线程运行到下面的for的时候,此时exitChan是空的,因为intChan一直在死循环等待,所以触发了死锁

  • 只读只写

  • var chanIn chan<- int//只写
    
  • var chanOut <-chan int//只读
    
  • select {case …}可以安全地取出数据

  • 使用recover捕获协程终端 panic


http://www.niftyadmin.cn/n/4979983.html

相关文章

什么是数据仓库?

数据仓库&#xff1a;DATA WAREHOUSE&#xff0c;简称数仓、DW。是一个用于存储、分析、报告的数据系统。目的是构建面向分析的集成化数据环境&#xff0c;为企业提供决策支持。 数仓本身不"产生"任何数据&#xff0c;其数据来源于不同的外部系统&#xff1b;同时数…

lnmp架构-mysql1

1.MySQL数据库编译 make完之后是这样的 mysql 初始化 所有这种默认不在系统环境中的路径里 就这样加 这样就可以直接调用 不用输入路径调用 2.初始化 重置密码 3.mysql主从复制 配置master 配置slave 当master 端中还没有插入数据时 在server2 上配slave 此时master 还没进…

在 Windows 下使用 conda 的一些注意点

之前一直使用 MacOS 或者 Ubuntu 作为开发环境&#xff0c;最近因为某些特殊原因需要转为使用 Window 作为开发环境。遇到的第一个问题就是不同开发工具的多环境管理。本文是关于 Windows 下使用 conda 的一些记录&#xff0c;关于如何在 Linux 做多环境管理&#xff0c;可以参…

Unity创建一个可移动的2D角色

文章目录 创建角色与场景创建地面 角色控制脚本检测地面 运行结果 创建角色与场景 我们首先创建一个角色&#xff0c;这里我新建了一个胶囊体用来当Player&#xff0c;一个Square用来当地面。 接下来&#xff0c;为角色增加碰撞体和刚体&#xff0c;为地面增加碰撞体。然后我…

教您制作企业宣传片视频模板

制作企业视频宣传片模板是一种有效的方式&#xff0c;可以让你在制作多个宣传视频时节省时间和资源。制作视频宣传片具有许多优点&#xff0c;包括吸引力强、情感打动、传播广泛和提升品牌形象。由深圳企业视频宣传片制作公司老友记小编从以下几个方面浅析一些制作企业视频宣传…

JavaScript—对象与构造方法

目录 json对象&#xff08;字面值&#xff09; js中对象是什么&#xff1f; 如何使用&#xff1f; 关联数组 js对象和C#对象有什么区别&#xff1f; 构造函数 什么是构造方法&#xff1f; 如何使用构造方法&#xff1f; 如何添加成员&#xff1f; 对象的动态成员 正则…

网络安全(黑客技术)0基础学习手册

目录梗概 一、自学网络安全学习的误区和陷阱 二、学习网络安全的一些前期准备 三、网络安全学习路线 四、学习资料的推荐 想自学网络安全&#xff08;黑客技术&#xff09;首先你得了解什么是网络安全&#xff01;什么是黑客&#xff01; 网络安全可以基于攻击和防御视角来…

自动化运维工具-----Ansible入门详解

目录 一.Ansible简介 什么是Ansible&#xff1f; Ansible的特点 Ansible的架构 二.Ansible任务执行解析 ansible任务执行模式 ansible执行流程 ansible命令执行过程 三.Ansible配置解析 ansible的安装方式 ansible的程序结构&#xff08;yum安装为例&#xff09; ansibl…