channel,work_pool and select are finished
parent
dd9b607ebe
commit
0aae887404
|
@ -50,3 +50,19 @@ M:N 复用/调度M的goroutine的到N个os线程
|
|||
一个操作系统的线程对应多个用户态的goroutine
|
||||
狗程序可以同时使用多个操作系统线程
|
||||
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