题目描述
使用goroutine和channel实现一个计算int64随机数各位数和的程序。
- 开启一个goroutine循环生成int64类型的随机数,发送到jobChan
- 开启24个goroutine从jobChan中取出随机数计算各位数的和,将结果发送到resultChan
- 主goroutine从resultChan取出结果并打印到终端输出
题解
1.限制生成个数,有缓冲区
package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
var wg sync.WaitGroup
func creater(id int, jobChan chan<- int64) {
defer wg.Done()
rand.Seed(time.Now().UnixNano())
for i := 1; i <= id; i++ {
fmt.Printf("creater start id:%d\n", i)
jobChan <- rand.Int63n(100) //[0,100)
fmt.Printf("creater end id:%d\n", i)
}
close(jobChan)
}
func calcer(id int, jobChan <-chan int64, resultChan chan<- int64) {
defer wg.Done()
fmt.Printf("calcer %d start calc!\n", id)
for {
num, ok := <-jobChan
if !ok {
break
}
colon := num
sum := int64(0)
for num > 0 {
sum += num % 10
num /= 10
}
resultChan <- sum
fmt.Printf("calcer %d end calc %d -----> %d !\n", id, colon, sum)
}
}
func printer(resultChan chan int64) {
for {
i, ok := <-resultChan
if !ok {
break
}
fmt.Println(i, ok)
}
}
func main() {
jobChan := make(chan int64, 100)
resultChan := make(chan int64, 100)
num := 10
wg.Add(1)
go creater(num, jobChan)
for i := 1; i <= 24; i++ {
wg.Add(1)
go calcer(i, jobChan, resultChan)
}
wg.Wait()
close(resultChan)
fmt.Println("printer()输出结果:")
printer(resultChan)
}
2.不限制生成个数,有缓冲区
package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
var wg sync.WaitGroup
func creater(jobChan chan<- int64) {
defer wg.Done()
rand.Seed(time.Now().UnixNano())
for i := 1; ; i++ {
fmt.Printf("creater start id:%d\n", i)
jobChan <- rand.Int63n(100) //[0,100)
fmt.Printf("creater end id:%d\n", i)
time.Sleep(time.Microsecond * 1000)
}
}
func calcer(id int, jobChan <-chan int64, resultChan chan<- int64) {
defer wg.Done()
fmt.Printf("calcer %d start calc!\n", id)
for {
num := <-jobChan
colon := num
sum := int64(0)
for num > 0 {
sum += num % 10
num /= 10
}
resultChan <- sum
fmt.Printf("calcer %d end calc %d -----> %d !\n", id, colon, sum)
}
}
func printer(resultChan chan int64) {
for i := range resultChan {
fmt.Println(i)
}
}
func main() {
jobChan := make(chan int64, 100)
resultChan := make(chan int64, 100)
wg.Add(1)
go creater(jobChan)
for i := 1; i <= 24; i++ {
wg.Add(1)
go calcer(i, jobChan, resultChan)
}
fmt.Println("printer()输出结果:")
printer(resultChan)
wg.Wait()
}
3.不限制生成个数,无缓冲区
package main
import (
"fmt"
"math/rand"
"time"
)
func creater(jobChan chan<- int64) {
rand.Seed(time.Now().UnixNano())
for i := 1; ; i++ {
fmt.Printf("creater start id:%d\n", i)
jobChan <- rand.Int63n(100) //[0,100)
fmt.Printf("creater end id:%d\n", i)
}
close(jobChan)
}
func calcer(id int, jobChan <-chan int64, resultChan chan<- int64) {
fmt.Printf("calcer %d start calc!\n", id)
for {
num := <-jobChan
colon := num
sum := int64(0)
for num > 0 {
sum += num % 10
num /= 10
}
resultChan <- sum
fmt.Printf("calcer %d end calc %d -----> %d !\n", id, colon, sum)
}
}
func printer(resultChan chan int64) {
for i := range resultChan {
fmt.Println(i)
}
}
func main() {
jobChan := make(chan int64)
resultChan := make(chan int64)
go creater(jobChan)
for i := 1; i <= 24; i++ {
go calcer(i, jobChan, resultChan)
}
fmt.Println("printer()输出结果:")
printer(resultChan)
}
4.Qimi代码
package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
// job ...
type job struct {
value int64
}
// Result ...
type result struct {
job *job
sum int64
}
var jobChan = make(chan *job, 100)
var resultChan = make(chan *result, 100)
var wg sync.WaitGroup
func zhoulin(zl chan<- *job) {
defer wg.Done()
// 循环生成int64类型的随机数,发送到jobChan
for {
x := rand.Int63()
newJob := &job{
value: x,
}
zl <- newJob
time.Sleep(time.Millisecond * 500)
}
}
func baodelu(zl <-chan *job, resultChan chan<- *result) {
defer wg.Done()
// 从jobChan中取出随机数计算各位数的和,将结果发送到resultChan
for {
job := <-zl
sum := int64(0)
n := job.value
for n > 0 {
sum += n % 10
n = n / 10
}
newResult := &result{
job: job,
sum: sum,
}
resultChan <- newResult
}
}
func main() {
wg.Add(1)
go zhoulin(jobChan)
// 开启24个goroutine执行保德路
wg.Add(24)
for i := 0; i < 24; i++ {
go baodelu(jobChan, resultChan)
}
// 主goroutine从resultChan取出结果并打印到终端输出
for result := range resultChan {
fmt.Printf("value:%d sum:%d\n", result.job.value, result.sum)
}
wg.Wait()
}