Q1mi / BlogComments

9 stars 0 forks source link

Go语言基础之并发 | 李文周的博客 #149

Open Q1mi opened 2 years ago

Q1mi commented 2 years ago

https://www.liwenzhou.com/posts/Go/concurrence/

李文周的 Blog 提供 Go 语言中文教程,李文周博客,Go 语言学习之路是我整理的一个免费教程和视频教程,也是Go语言的入门教程,非常适合新手入门学习go语言。本文介绍了Go语言并发的并发元语:goroutine channel go 线程 进程 锁 互斥锁 读写锁 原子 atomic

Luozongwei commented 2 years ago

作为初学者的我 刚好看到这里就更新了 嘿嘿嘿

liujing-siyang commented 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()
}
kindleheart commented 2 years ago
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)
    }
}
zosen-wang commented 2 years ago

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
    }
}
ChaconneLuo commented 2 years ago
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)
    }
}
cht452 commented 2 years ago

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) } }

hosome17 commented 2 years ago
  1. 单向通道那一小节,第一段话的最后那句里 Processer 好像打错了,应该是Producer吧
  2. 多返回值那一小节,并不是通道关闭后返回给 value 的值就是零值,而是应该会先返回通道关闭前缓冲的值,当通道没数据了才会返回零值吧
  3. 通道关闭了不一定返回给 ok 就是 false,通道仍有关闭前缓冲的值存在仍返回 true
    
    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

callmePicacho commented 1 year ago
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
}
LiiiYooo commented 1 year ago
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
        }
    }
}
xiehaojie commented 1 year ago

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)
}

}

chaomingd commented 6 months ago
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
    }
}
youngzhenhao commented 2 weeks ago
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
    }
}