goroutine和channel
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视频的学习做的笔记。