channel,work_pool and select are finished
parent
dd9b607ebe
commit
0aae887404
|
@ -50,3 +50,19 @@ M:N 复用/调度M的goroutine的到N个os线程
|
||||||
一个操作系统的线程对应多个用户态的goroutine
|
一个操作系统的线程对应多个用户态的goroutine
|
||||||
狗程序可以同时使用多个操作系统线程
|
狗程序可以同时使用多个操作系统线程
|
||||||
goroutine和os线程时多对多的关系,即M:N
|
goroutine和os线程时多对多的关系,即M:N
|
||||||
|
|
||||||
|
|
||||||
|
select多路复用
|
||||||
|
Select 的使用方式类似于之前学到的 switch 语句,它也有一系列 case 分支和一个默认的分支。
|
||||||
|
每个 case 分支会对应一个通道的通信(接收或发送)过程。select 会一直等待,直到其中的某个 case 的通信操作完成时,就会执行该 case 分支对应的语句。具体格式如下:
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-ch1:
|
||||||
|
//...
|
||||||
|
case data := <-ch2:
|
||||||
|
//...
|
||||||
|
case ch3 <- 10:
|
||||||
|
//...
|
||||||
|
default:
|
||||||
|
//默认操作
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
// channel练习
|
||||||
|
|
||||||
|
var WG sync.WaitGroup
|
||||||
|
|
||||||
|
// 1.启动一个goroutine生成100个数字,发送到ch1
|
||||||
|
func set100Num(ch1 chan<- int) { //在声明后添加符号类型表示单向通道
|
||||||
|
defer WG.Done()
|
||||||
|
for i := 0; i < 100; i++ {
|
||||||
|
ch1 <- i
|
||||||
|
}
|
||||||
|
close(ch1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2.启动一个goroutine从ch1中取值,计算其平方,放到ch2中
|
||||||
|
func get100Num(ch1 <-chan int, ch2 chan<- int) {
|
||||||
|
defer WG.Done()
|
||||||
|
for {
|
||||||
|
x, ok := <-ch1
|
||||||
|
if !ok {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
ch2 <- x * x
|
||||||
|
}
|
||||||
|
close(ch2)
|
||||||
|
}
|
||||||
|
|
||||||
|
//3.在main函数中从ch2中取值,打印出来
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
e := make(chan int, 50)
|
||||||
|
f := make(chan int, 100)
|
||||||
|
WG.Add(2)
|
||||||
|
go set100Num(e)
|
||||||
|
go get100Num(e, f)
|
||||||
|
WG.Wait()
|
||||||
|
for ret := range f {
|
||||||
|
fmt.Printf("通道中数字的平方是:%v\n", ret)
|
||||||
|
}
|
||||||
|
ch3 := make(chan int, 2)
|
||||||
|
ch3 <- 10
|
||||||
|
ch3 <- 20
|
||||||
|
<-ch3
|
||||||
|
<-ch3
|
||||||
|
close(ch3) //取完值后关闭通道
|
||||||
|
t, ok := <-ch3
|
||||||
|
//第三次仍能取到
|
||||||
|
fmt.Println("第三此取出的值为", ok, t)
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
//第一次1,select选择一个能执行的即 ch<-i,把1放入通道,第二次,不能放入,取出,第三次再放入,第四次再取出
|
||||||
|
ch := make(chan int, 1)
|
||||||
|
for i := 1; i <= 10; i++ {
|
||||||
|
select {
|
||||||
|
case x := <-ch:
|
||||||
|
fmt.Println(x)
|
||||||
|
case ch <- i:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func worker(id int, jobs <-chan int, results chan<- int) {
|
||||||
|
for j := range jobs {
|
||||||
|
fmt.Println("worker", id, "started job", j)
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
fmt.Println("worker", id, "finished job", j)
|
||||||
|
results <- j * 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// work_pool练习
|
||||||
|
func main() {
|
||||||
|
jobs := make(chan int, 100)
|
||||||
|
results := make(chan int, 100)
|
||||||
|
//开启三个goroutine
|
||||||
|
for w := 1; w <= 3; w++ {
|
||||||
|
go worker(w, jobs, results)
|
||||||
|
}
|
||||||
|
//五个任务,0-5的数字放到jobs这个通道中
|
||||||
|
for j := 1; j <= 5; j++ {
|
||||||
|
jobs <- j
|
||||||
|
}
|
||||||
|
//关闭job
|
||||||
|
close(jobs)
|
||||||
|
//把results这个通道中的数字,即jobs中的结果*2取出
|
||||||
|
for a := 1; a <= 5; a++ {
|
||||||
|
<-results
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
//使用 goroutine 和 channel 实现一个计算int64随机数各位数和的程序,例如生成随机数61345,计算其每个位数上的数字之和为19。
|
||||||
|
//开启一个 goroutine 循环生成int64类型的随机数,发送到jobChan
|
||||||
|
//开启24个 goroutine 从jobChan中取出随机数计算各位数的和,将结果发送到resultChan
|
||||||
|
//主 goroutine 从resultChan取出结果并打印到终端输出
|
||||||
|
|
||||||
|
var w sync.WaitGroup
|
||||||
|
|
||||||
|
type job struct {
|
||||||
|
value int64
|
||||||
|
}
|
||||||
|
type Result struct {
|
||||||
|
job *job
|
||||||
|
sum int64
|
||||||
|
}
|
||||||
|
|
||||||
|
var jobChan = make(chan *job, 100)
|
||||||
|
var resultChan = make(chan *Result, 100)
|
||||||
|
|
||||||
|
func producer(prod chan<- *job) <-chan *job {
|
||||||
|
defer w.Done()
|
||||||
|
for {
|
||||||
|
x := rand.Int63()
|
||||||
|
newJob := &job{value: x}
|
||||||
|
jobChan <- newJob
|
||||||
|
time.Sleep(time.Millisecond * 500)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func consumer(con chan<- *Result, prod <-chan *job) {
|
||||||
|
defer w.Done()
|
||||||
|
for {
|
||||||
|
v := <-prod
|
||||||
|
sum := int64(0)
|
||||||
|
n := v.value
|
||||||
|
for n > 0 {
|
||||||
|
sum += n % 10
|
||||||
|
n = n / 10
|
||||||
|
}
|
||||||
|
newResult := &Result{job: v, sum: sum}
|
||||||
|
con <- newResult
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
w.Add(1)
|
||||||
|
go producer(jobChan)
|
||||||
|
w.Add(24)
|
||||||
|
for i := 0; i < 24; i++ {
|
||||||
|
go consumer(resultChan, jobChan)
|
||||||
|
}
|
||||||
|
for i := range resultChan {
|
||||||
|
fmt.Printf("随机数为:%d,加和为:%d\n", i.job.value, i.sum)
|
||||||
|
}
|
||||||
|
w.Wait()
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue