并发
多个进程快速交替执行,进程在几个时间区之间来回切换,进程其实是串行的,但是在宏观上让用户感觉多个进程是同时进行的
并行
多个进程在同一时刻同事执行,这是并行的。
进程,线程,协程
1 进程和线程由操作系统管理,协程是由程序控制的
2 进程可以包含多个线程,线程可以包含多个协程
3 同一个进程中的多个线程之间的资源可以共享,协程本质是一个函数
4 进程和线程可以并行或者串行,但是协程必须是串行。
通道
通道是用来传递数据的一种数据结构
ch <- "data" //接收数据
data <- ch //发送数据
GO语言中使用并发
只需要通过(go 执行的语句)就可以开启groutine, 简洁轻量。
go foo()
下面是展示了阻塞的情况,还有使用通道缓存。
package main
import (
"fmt"
"time"
)
func main () {
//SelectTest()
test()
}
//正常执行,接收数据和发送数据正常,不会阻塞。
func GoCurent1() {
ch := make(chan string)
go func() {
fmt.Println("Start")
ch <- "singal"
fmt.Println("Stop")
}()
fmt.Println("wait")
<-ch
fmt.Println("Done")
}
// ch没有接收数据,因此 <-ch 发送数据的时候阻塞
// err : fatal error: all goroutines are asleep - deadlock!
// result:wait Start Stop
func GoCurent2() {
ch := make(chan string)
go func() {
fmt.Println("Start")
// ch <- "singal"
fmt.Println("Stop")
}()
fmt.Println("wait")
<-ch
fmt.Println("Done")
}
// ch没有发送数据,因此 ch <- "singal" 接收数据的时候阻塞
// err : fatal error: all goroutines are asleep - deadlock!
//result : wait Done
func GoCurent3() {
ch := make(chan string)
go func() {
fmt.Println("Start")
ch <- "singal"
fmt.Println("Stop")
}()
fmt.Println("wait")
// <-ch
fmt.Println("Done")
}
func SelectTest() {
ch := make(chan string)
timeout := make(chan bool, 1)
go func() {
ch <- "gogo"
time.Sleep(5)
timeout <- true
}()
select {
case <-ch:
fmt.Println("I am ch")
break
case <-timeout:
fmt.Println("I am timeout")
break
}
}
func fibonnacci(n int, ch chan int) {
a, b := 0,1
for i:=0; i<n; i++ {
ch <- a
a, b = b, a+b
}
//如果ch接收不到数据的时候关闭通道。
close(ch)
}
func test() {
//cap(ch) 获取通道的容量
ch := make(chan int, 7)
go fibonnacci(cap(ch), ch)
for j:= range ch {
fmt.Println(j)
}
}