这是我参与[第五届青训营]的第十三天
- Web是基于HTTP协议进行交互的应用网络 HTTP1.1
- Web就是通过使用浏览器/APP访问的各种资源
一般来说使用并行程序中,最常遇到的问题有:
- 多线程相互通信
- 等待一个程序结束后再接着工作
- 多个并行程序使用同一个变量
- 不同线程产出影响后续逻辑
- 兄弟线程间共同同时结束
并发concurrency是将process切割成多个可执行单位(coroutine),如果有多个process时则在coroutine中交互执行,这样不会因为某一个process执行太久而造成其他process无法处理,会让我们有多工的感觉,但这并不会增加执行效率。
go routine的通信主要可以通过channel、全局变量进行操作。
首先channel的部分,声明通过chan关键字,配合make关键字申请空间。
package main
import(
"fmt"
"time"
)
//示例:channel控制线程,收集两个执行序的数据1、2
func main(){
//宣告channel make(chan型态<容量>)
val:= make(chan int)
//执行第一个线程
go func(){
fmt.Println("intput val 1")
val <- 1 //注入数据1
}()
//执行第二个线程
go func(){
fmt.Println("intput val 2")
val <- 2 //注入数据2
time.Sleep(time.Millisecond * 100)
}()
ans:= []int{}
for {
ans = append(ans,<-val)//取出数据
fmt.Println(ans)
if len(ans)== 2 {
break
}
}
}
另一个方式就是比较传统的方式进行存取,直接使用变量进行存取,
package main
import(
"fmt"
"time"
)
//示例:共享变数
func main(){
val:= 1
//执行第一个线程
go func(){
fmt.Println("first",val)
}()
//执行第二个线程
go func(){
fmt.Println("sec",val)
}()
time.Sleep(time.Millisecond * 500)
}
如果比较熟悉Java的话可以联想到Join的概念,而在Golang中要做到等待的这件事情有两个方法,一个是sync.WaitGroup、另一个是channel。
Sync.WaitGroup像是一个计数器,启动一条Goroutine计数器+1;反之结束一条-1。若计数器为复数代表Error。
package main
import(
"log"
"sync"
"time"
)
//示例:等待一线程结束后再接续工作(使用WaitGroup)
func main(){
var wg sync.WaitGroup
//执行线程
go func(){
defer wg.Done()//defer表示最后执行,因此该行为最后执行wg.Done()将计数器-1
defer log.Println("goroutine drop out")
log.Println("start a go routine")
time.Sleep(time.Second)//休息一秒钟
}()
wg.Add(1)//计数器+1
time.Sleep(time.Millisecond * 30)//休息30 ms
log.Println("wait a goroutine")
wg.Wait()//等待计数器归0
}