go语言学习(六)——并发编程
并发编程这块断断续续看了挺久的,&感觉还是有地方没有理解。有时间还是要找找正式的代码看一看,不然不知道怎么用啊。
有些地方不清楚该怎么用,所以下面写的有些乱,再有新的理解再进行补充。。。
// GoStudy0228 project main.go
/*
go语言学习——并发编程
go语言中支持轻量级线程goroutine
go语言中以消息机制作为通信方式
*/
package main
import (
"fmt"
"sync"
"time"
)
func main() { //程序从这开始执行
v1 := make(chan [2]int) //定义chan,这里的chan用来传递一个大小为2的int数组
v2 := [2]int{1, 2} //定义数组
var v3 chan bool = make(chan bool, 10) //另一种定义chan的方式,后面的10,是缓存空间的大小,缓存区在被填满的时候是阻塞的
go Add(v1, v3) //go关键字启动goroutine
v1 <- v2 //将v2传入chan,在goroutine没有创建的时候,不能向v1传值。
var v4 bool = <-v3 //这里进行阻塞,直到Add函数向chan中传入值以后才能够继续运行。不然可能goroutine没有执行完,main就已经执行完了。
fmt.Println(v4) //可以将Add函数的isFinished去掉,然后运行看结果,就知道为什么要额外加一个chan了
v6 := make(chan int, 10)
timeOut := make(chan bool)
go TimeWait(timeOut) //一种超时处理方式,但目前没有理解号怎么用
select { //类似于switch,但是只能用于IO方面
case <-v6: //
fmt.Println("从v6读取数据")
break
case <-timeOut:
fmt.Println("超时")
break
default:
// fmt.Println("+++++++++++")
}
//------------------------------
//单向chan的创建
//v21 := make(chan int, 1024) //基于v21创建单向chan
//v22 := <-chan int(v21) //只读
//v23 := chan<- int(v21) //只写
close(v1) //关闭管道v1
_, ok1 := <-v1
fmt.Println("v1 is open?", ok1)
//------------------------------
//同步锁
//var v31 sync.Mutex int//单一读写
//var v32 sync.RWMutex float32//单写多读
//v31.Lock()//锁定和解锁要对应,否则死锁卡死
//defer v31.Unlock()//这个函数崩溃的时候执行这句,解除锁定
//v32.RLock()
//defer v32.RUnlock()
//------------------------------
var v41 sync.Once //全局唯一,多个调用的时候,会阻塞,一个执行完才进行下一个
v41.Do(func() {
fmt.Println("Hello World!!")
})
} //程序运行到这退出
func Add(ch chan [2]int, isFinished chan bool) {
nums := <-ch //chan被读取前,这里是阻塞的
for i := 0; i < 100; i++ {
fmt.Println("NO.", i, ":", nums[0]+nums[1])
}
isFinished <- true
}
func TimeWait(isFinished chan bool) { //等待函数
time.Sleep(1) //等待一秒
isFinished <- true
}
/*
几种多线程的方式
1.多进程,操作系统层面,开销大
2.多线程,系统层面,使用最多,最有效,开销较大,高并发对性能有影响
3.基于回掉的非阻塞/异步IO,通过事件驱动方式使用异步IO,尽可能少用线程,降低开销,但编程比多线程要复杂
4.协程,有效解决高并发问题,系统开销极小,编程简单,结构清晰,但是需要语言支持(或者用户自行拓展)
*/
/*
线程间通信:共享内存模式,消息传递模式
*/
//:)

浙公网安备 33010602011771号