Open Q1mi opened 2 years ago
作为初学者的我 刚好看到这里就更新了 嘿嘿嘿
import (
"fmt"
"math/rand"
"sync"
"time"
)
var wg sync.WaitGroup
var once sync.Once
func f1(jobChan chan int64) {
for i := 0; i < 100; i++ {
r := rand.New(rand.NewSource(time.Now().UnixNano()))
num := r.Int63()
jobChan <- num
time.Sleep(time.Millisecond * 10)
}
close(jobChan)
wg.Done()
}
func f2(jobChan chan int64, resultChan chan int64) {
for {
num,ok:= <-jobChan
if !ok{
once.Do(func(){
close(resultChan)
})
break
}
var t int64
for num > 0 {
left := num % 10
num = num / 10
t += left
}
resultChan <- t
}
wg.Done()
}
func main() {
jobChan := make(chan int64, 1)
resultChan := make(chan int64, 24)
wg.Add(1)
go f1(jobChan)
for i := 0; i < 24; i++ {
wg.Add(1)
go f2(jobChan, resultChan)
}
for num := range resultChan {
fmt.Println(num)
}
wg.Wait()
}
package main
import (
"fmt"
"math/rand"
"sync"
)
var wg sync.WaitGroup
func createRandNumber() <-chan int64 {
jobChan := make(chan int64, 10)
go func() {
for i := 0; i < 100; i++ {
jobChan <- rand.Int63()
}
close(jobChan)
}()
return jobChan
}
func calculate(jobChan <-chan int64, resultChan chan<- int) {
defer wg.Done()
for num := range jobChan {
sum := 0
for num > 0 {
sum += int(num % 10)
num /= 10
}
resultChan <- sum
}
}
func main() {
jobChan := createRandNumber()
resultChan := make(chan int, 100)
for i := 0; i < 24; i++ {
wg.Add(1)
go calculate(jobChan, resultChan)
}
go func() {
wg.Wait()
close(resultChan)
}()
for v := range resultChan {
fmt.Println(v)
}
}
package main
import (
"fmt"
"math/rand"
"sync"
)
var wg sync.WaitGroup
func main() {
wg.Add(1)
jobChan := make(chan int64, 1)
resultChan := make(chan int64, 100)
go randNum(jobChan)
for i := 0; i < 24; i++ {
wg.Add(1)
go sumNum(jobChan, resultChan)
}
close(resultChan)
for ret := range resultChan {
fmt.Println(ret)
}
wg.Wait()
}
func randNum(jobChan chan<- int64) {
defer wg.Done()
for i := 0; i < 100; i++ {
jobChan <- rand.Int63()
}
close(jobChan)
}
func sumNum(jobChan <-chan int64, resultChan chan<- int64) {
defer wg.Done()
for v := range jobChan {
var s int64
for v > 0 {
s += v % 10
v = v / 10
}
resultChan <- s
}
}
package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
var wg sync.WaitGroup // WaitGroup is a value type
func cal(x int64) int64 {
var res int64 = 0
for x != 0 {
res += x % 10
x /= 10
}
return res
}
func randNum() <-chan int64 {
defer wg.Done()
wg.Add(1)
ch := make(chan int64, 200)
go func() {
for i := 0; i < 200; i++ {
r := rand.New(rand.NewSource(time.Now().UnixNano()))
ch <- r.Int63()
}
close(ch)
}()
return ch
}
func start(jobChan <-chan int64, resultChan chan int64) {
defer wg.Done()
wg.Add(1)
for {
num, ok := <-jobChan
if ok {
resultChan <- cal(num)
} else {
break
}
}
}
func main() {
jobChan := randNum()
resultChan := make(chan int64, 10)
for i := 0; i < 24; i++ {
go start(jobChan, resultChan)
}
go func() {
wg.Wait()
close(resultChan)
}()
for num := range resultChan {
fmt.Println(num)
}
}
package main
import ( "fmt" "math/rand" "sync" "time" )
var wg sync.WaitGroup
func f1(jobChan chan<- int64) { defer wg.Done() for i := 0; i < 10; i++ { random := rand.New(rand.NewSource(time.Now().UnixNano())) num := random.Int63() jobChan <- num //time.Sleep(time.Millisecond * 10) } close(jobChan) }
func f2(jobChan <-chan int64, resultChan chan<- int64) { defer wg.Done() for ret := range jobChan { var sum int64 for ret > 0 { sum = sum + (ret % 10) ret = ret / 10 } resultChan <- sum } }
func main() { wg.Add(1) var jobChan = make(chan int64, 100) var resultChan = make(chan int64, 24) go f1(jobChan) for i := 0; i < 10; i++ { wg.Add(1) go f2(jobChan, resultChan) } wg.Wait() // 参考了楼上几位同学的解法,发现wg.Wait()要放在resultChan关闭之前, //不然会报“往关闭的通道里写入数据的错误" close(resultChan) for sum := range resultChan { fmt.Printf("sum:=%v\n", sum) } }
func function(ch chan int) {
for i:= 0; i < 10; i++ {
v, ok := <-ch
fmt.Printf("v:%#v ok:%#v\n", v, ok)
time.Sleep(time.Second)
}
}
func main() { ch := make(chan int, 10) ch <- 1 ch <- 2 ch <- 3 ch <- 4 ch <- 5 close(ch) function(ch) }
output: v:1 ok:true v:2 ok:true v:3 ok:true v:4 ok:true v:5 ok:true v:0 ok:false v:0 ok:false v:0 ok:false v:0 ok:false v:0 ok:false
package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
// 1. 使用 goroutine 和 channel 实现一个计算int64随机数各位数和的程序,
// 例如生成随机数61345,计算其每个位数上的数字之和为19
// 1. 开启一个 goroutine 循环生成int64类型的随机数,发送到jobChan
// 2. 开启24个 goroutine 从jobChan中取出随机数计算各位数的和,将结果发送到resultChan
// 3. 主 goroutine 从resultChan取出结果并打印到终端输出
func main() {
jobChan := make(chan int64, 20)
resultChan := make(chan int, 10)
rand.Seed(time.Now().UnixNano())
go func() {
for i := 0; i < 1000; i++ {
jobChan <- rand.Int63()
}
close(jobChan)
}()
var wg sync.WaitGroup
for i := 0; i < 24; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for v := range jobChan {
resultChan <- getSum(v)
}
}()
}
go func() {
wg.Wait()
close(resultChan)
}()
for v := range resultChan {
fmt.Println(v)
}
}
func getSum(x int64) int {
sum := 0
for x != 0 {
sum += int(x % 10)
x /= 10
}
return sum
}
package main
import (
"fmt"
"math/rand"
"time"
)
/**
使用goroutine和channel来实现一个计算随机数个位数和的一个程序
1.开启一个goroutine循环生成一个随机数,发送到jobChan
2.开启24个goroutine从jobChan中取出然后计算各位数的和放到resultChan
3.主goroutine从resultChan取出结果并打印到终端输出
*/
//定义一个job结构体
type job struct {
num int64
}
//初始化两个channel
var (
jobChan = make(chan *job, 4)
resultChan = make(chan int64, 4)
)
func main() {
go makeJob(jobChan)
for i := 0; i < 24; i++ {
go doJob(i, jobChan, resultChan)
}
for true {
<-resultChan
}
}
//生成job
func makeJob(jobChan chan<- *job) {
for true {
//埋时间种子
rand.Seed(time.Now().UnixNano())
//生成一个随机数 填充到结构体中
jobChan <- &job{num: rand.Int63()}
//一秒生产一个
time.Sleep(time.Second)
}
}
func doJob(goroutineNo int, jobChan <-chan *job, resultChan chan<- int64) {
for true {
for job := range jobChan {
var result int64
num := job.num
History := num
for {
if num <= 0 {
break
}
//求余数得出相加的值
value := num % 10
num = num / 10
result += value
}
fmt.Printf("goroutineNo=%d,计算前的num=%d,计算完的result=%d\n", goroutineNo, History, result)
resultChan <- result
}
}
}
import ( "fmt" "math/rand" "strconv" "strings" "sync" "time" )
var swg sync.WaitGroup
func generateRandomInt(min, max int, ch chan<- int64) { for i := 0; i < 10; i++ { temp := int64(rand.Intn(max-min) + min) ch <- temp fmt.Println("随机数是啥:", temp) } close(ch) swg.Done() }
func computeRandomInt(job <-chan int64, result chan<- int) {
for v := range job {
result <- computeItem(v)
}
swg.Done()
}
// 计算位数 func computeItem(v int64) int { tmp := strings.Split(strconv.Itoa(int(v)), "") tempSum := 0 for , v := range tmp { item, := strconv.Atoi(v) tempSum += item } return tempSum }
func Homework() { rand.Seed(time.Now().Unix()) //Seed生成的随机数
jobChan := make(chan int64, 10)
resultChan := make(chan int, 10)
swg.Add(1)
go generateRandomInt(10000, 99999, jobChan)
for i := 0; i < 24; i++ {
swg.Add(1)
go computeRandomInt(jobChan, resultChan)
}
swg.Wait()
close(resultChan)
for v := range resultChan {
fmt.Println("各个位置和为:", v)
}
}
package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
func main() {
jobChan := make(chan int64, 100)
resultChan := make(chan int64, 100)
random := rand.New(rand.NewSource(time.Now().UnixNano()))
wg := &sync.WaitGroup{}
go func() {
for i := 0; i < 100; i++ {
jobChan <- random.Int63()
}
close(jobChan)
}()
for i := 0; i < 24; i++ {
wg.Add(1)
go calcSum(jobChan, resultChan, wg)
}
go func() {
wg.Wait()
close(resultChan)
}()
for n := range resultChan {
fmt.Println(n)
}
}
func calcSum(jobChan <-chan int64, resultChan chan<- int64, wg *sync.WaitGroup) {
defer wg.Done()
for n := range jobChan {
sum := int64(0)
for n > 0 {
sum += (n % 10)
n /= 10
}
resultChan <- sum
}
}
package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
var wg sync.WaitGroup
func main() {
jobChan := make(chan int64, 100)
resultChan := make(chan int64, 100)
defer close(jobChan)
defer close(resultChan)
go f1(jobChan)
wg.Add(24)
for range 24 {
go f2(jobChan, resultChan)
}
for sum := range resultChan {
fmt.Println(sum)
}
wg.Wait()
}
func f1(jobChan chan<- int64) {
for {
jobChan <- rand.Int63()
// 1 Second = 1000 * Millisecond
time.Sleep(1000 * time.Millisecond)
}
}
func f2(jobChan <-chan int64, resultChan chan<- int64) {
defer wg.Done()
for num := range jobChan {
var sum int64
for num > 0 {
sum += num % 10
num /= 10
}
resultChan <- sum
}
}
https://www.liwenzhou.com/posts/Go/concurrence/
李文周的 Blog 提供 Go 语言中文教程,李文周博客,Go 语言学习之路是我整理的一个免费教程和视频教程,也是Go语言的入门教程,非常适合新手入门学习go语言。本文介绍了Go语言并发的并发元语:goroutine channel go 线程 进程 锁 互斥锁 读写锁 原子 atomic