GO协程初识
package main
import (
"fmt"
"sync"
"time"
)
func read() {
defer wg.Done()
fmt.Println("read start")
time.Sleep(time.Second * 3)
fmt.Println("read end")
}
func listenMusci() {
defer wg.Done()
fmt.Println("listenMusci start")
time.Sleep(time.Second * 5)
fmt.Println("listenMusci end")
}
var wg sync.WaitGroup //声明一把锁,同步的一个等待锁,本质是一个计时器,所有的进程都可以共享
func main() {
start := time.Now().Unix()
wg.Add(2)
go read() //开启GO并发
go listenMusci() //开启GO并发
wg.Wait() //计数器为0继续执行
//time.Sleep(time.Second * 10) //将main主线程阻塞下
end := time.Now().Unix()
fmt.Println(end - start)
}
输出结果:
互斥锁
package main
import (
"fmt"
"sync"
"time"
)
/*
互斥锁!!!
互斥锁是一种常用的控制共享资源访问的方法,它能够保证同时只有
一个goroutine可以访问共享资源。Go语言中使用sync包的Mutex类型来实现互斥锁。
使用互斥锁能够保证同一时间有且只有一个goroutine进入临界区,
其他的goroutine则在等待锁;当互斥锁释放后,等待的goroutine才可以获取锁进入临界区,
多个goroutine同时等待一个锁时,唤醒的策略是随机的。
*/
var wg sync.WaitGroup //声明一把锁,同步的一个等待锁,本质是一个计时器,所有的进程都可以共享
var lock sync.Mutex
var x = 0
func add() {
defer wg.Done()
//加锁,互斥锁
lock.Lock()
x++
lock.Unlock()
println(x)
time.Sleep(time.Second * 10) //
}
func main() {
wg.Add(100)
for i := 0; i < 100; i++ {
go add()
}
wg.Wait() //计数器为0继续执行
fmt.Println(x)
}
管道:channel的读写操作
package main
import (
"fmt"
"reflect"
)
/*
管道:channel的读写操作!!!
chan是go的协程之间通信的数据类型(引用类型)
没有索引的概念,取完第一个才能取第二个
*/
func 声明一个管道() {
//声明一个管道
var ch = make(chan int, 3)
//插入值
ch <- 12
ch <- 13
ch <- 15
//取值
fmt.Println(<-ch)
fmt.Println(<-ch)
fmt.Println(<-ch)
}
//声明一个结构体
type Msg struct {
content string
from string
}
func main() {
var ch = make(chan interface{}, 6)
ch <- "hello"
ch <- true
ch <- 15
ch <- Msg{content: "from kegog", from: "中国北京"}
one := <-ch
fmt.Println(one, reflect.TypeOf(one))
fmt.Println(<-ch)
fmt.Println(<-ch)
//fmt.Println(<-ch)
fmt.Println((<-ch).(Msg).content)
}
管道关闭后不能再写入值了
package main
import "fmt"
/*
管道的关闭与循环!!
*/
func 管道关闭后不能再写入值了() {
ch3 := make(chan int, 10)
ch3 <- 1
ch3 <- 2
ch3 <- 3
close(ch3)
fmt.Println(<-ch3)
ch3 <- 4
}
func main() {
管道关闭后不能再写入值了()
}
遍历管道之前要先关闭管道close
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int, 10)
ch <- 1
ch <- 2
ch <- 3
// 方式1
go func() {
time.Sleep(time.Second * 10)
ch <- 4
}()
for v := range ch {
fmt.Println(v, len(ch))
// 读取完所有值后,ch的sendq中没有groutine
if len(ch) == 0 { // 如果现有数据量为0,跳出循环
break
}
}
close(ch)
for i := range ch {
fmt.Println(i)
}
}
生产者消费者
package main
import (
"fmt"
"sync"
"time"
)
func producer(ch chan<- int) {
defer wg.Done()
for i := 1; i < 11; i++ {
time.Sleep(time.Second)
ch <- i
fmt.Println("生产了:", i)
}
close(ch)
}
func consumer(ch <-chan int) {
defer wg.Done()
for i := range ch {
fmt.Println("消费了:", i)
}
}
var wg sync.WaitGroup
func main() {
ch := make(chan int, 100)
wg.Add(2)
go producer(ch)
go consumer(ch)
wg.Wait()
fmt.Println("process end")
}