【Golang的goroutine和channel】

本文详细介绍了Go语言中的goroutine和channel。goroutine作为轻量级线程,用于提高程序运行速度,通过示例展示了其快速入门及调度模型。channel作为goroutine间的通信机制,解决了多线程同步问题,文中通过实例演示了其创建、遍历、关闭及使用注意事项。此外,还探讨了channel在并发安全中的应用。
摘要由CSDN通过智能技术生成

goroutine需求

在这里插入图片描述目的:提高运行速度


goroutine基本介绍

程序、进程、线程的区别并行和并发


goroutine快速入门

package main
import (
	"fmt"
	"time"
	"strconv"
)
func test(){
	for i:=1;i<=10;i++{
		fmt.Println("test"+strconv.Itoa(i))
		time.Sleep(time.Second)
	}
}
func main(){
	go test()
	for i:=1;i<=10;i++{
		fmt.Println("main"+strconv.Itoa(i))
		time.Sleep(time.Second)
	}
}//没有time.Sleep连test都执行不了

在这里插入图片描述
在这里插入图片描述


goroutine的调度模型

在这里插入图片描述1)MPG模式运行的状态1
在这里插入图片描述2)MPG模式运行的状态2
在这里插入图片描述

channel需求

在这里插入图片描述解决多线程同时读取以及主线程等待的问题

互斥锁:不同协程共同等待操作一块相同的空间,缺点就是主线程的等待过程

package main
import(
	"fmt"
	"runtime"
	"time"
	"sync"
)
var(
	myMap=make(map[int]int,10)
	lock sync.Mutex
)
func test(n int){
	res:=1
	for i:=1;i<=n;i++{
		res*=i
	}
	lock.Lock()
	myMap[n]=res
	lock.Unlock()
}
func main(){
	num:=runtime.NumCPU()
	fmt.Println(num)
	for i:=1;i<=200;i++{
		go test(i)
	}
	time.Sleep(time.Second*10)
	lock.Lock()
	for i,v:=range myMap{
		fmt.Printf("map[%d]=%d\n",i,v)
	}
	lock.Unlock()
}

在这里插入图片描述

channel的基本介绍

在这里插入图片描述在这里插入图片描述

package main
import(
	"fmt"
)
func main(){
	var intChan chan int
	intChan=make(chan int,3)
	fmt.Printf("intChan的值=%v intChan的地址%p",intChan,&intChan)
	intChan<-10
	intChan<-20
	num:=211
	intChan<-num
	fmt.Printf("len=%v cap=%v",len(intChan),cap(intChan))
	var num2 int
	num2=<-intChan
	num3:=<-intChan
	num4:=<-intChan
	fmt.Println("num2:",num2,"num3:",num3,"num4",num4)
}
package main
import(
	"fmt"
)
func main(){
	// var mapChan chan map[string]string
	// mapChan=make(chan map[string]string,10)
	// m1:=make(map[string]string,20)
	// m2:=make(map[string]string,20)
	// m1["aaa"]="111"
	// m1["bbb"]="222"
	// m2["ccc"]="333"
	// m2["ddd"]="444"
	// mapChan<-m1
	// mapChan<-m2
	// fmt.Println(mapChan)
	type Cat struct{
		Name string
		Age int
	}
	var allChan chan interface{}
	allChan=make(chan interface{},10)
	cat1:=Cat{Name:"tom",Age:18}
	cat2:=Cat{Name:"tom~",Age:180}
	allChan<-cat1
	allChan<-cat2
	allChan<-10
	allChan<-"tom"
	cat11:=<-allChan
	a:=cat11.(Cat)
	fmt.Println(a.Name)
}

channel的遍历和关闭

package main
import(
	"fmt"
)
func main(){
	intChan2:=make(chan int ,100)
	for i:=0;i<100;i++{
		intChan2<-i*2
	}
	close(intChan2)
	for v:=range intChan2{
		fmt.Println("v=",v)
	}
}

在这里插入图片描述

package main
import(
	"fmt"
	_"time"
)
func writeData(intChan chan int){
	for i:=0;i<=50;i++{
		intChan<-i
		fmt.Println("writeData",i)
		//time.Sleep(time.Second)
	}
	close(intChan)
}
func readData(intChan chan int,exitChan chan bool){
	for{
		v,ok:=<-intChan
		if!ok{
			break
		}
		fmt.Printf("readData 读到数据=%v\n",v)
		//time.Sleep(time.Second)
	}
	exitChan<-true
	close(exitChan)
}
func main(){
	intChan :=make(chan int,50)
	exitChan:=make(chan bool,1)
	go writeData(intChan)
	go readData(intChan,exitChan)
	//time.Sleep(time.Second*10)
	for{
		_,ok:=<-exitChan
		if!ok{
			break
		}
	}
}

channel的使用细节和注意事项

1)channel 可以声明为只读,或者只写性质
在这里插入图片描述2)在文件没有关闭的情况下遍历数据用select
3)一个线程错误,为了防止其他线程受到影响可以用recover


总结

本文仅仅简单介绍了Golang的goroutine和channel,此篇是通过b站尚硅谷Golang视频的学习做的笔记。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值