statefule goroutines _ golang

In the previous example we used explicit locking with mutexes to synchronize access to shared state across multiple goroutines. Another option is to use the built-in synchronization features of goroutines and channels to achieve the same result. This channel-based approach aligns with Go‘s ideas of sharing memory by communivating and having each piece of data owned by exactly 1 goroutine

package main

import (
    "fmt"
    "math/rand"
    "sync/atomic"
    "time"
)

type read0p struct {
    key  int
    resp chan int
}

type write0p struct {
    key  int
    val  int
    resp chan bool
}

func main() {

    var ops int64 = 0

    reads := make(chan *read0p)
    writes := make(chan *write0p)

    go func() {
        var state = make(map[int]int)
        for {
            select {
            case read := <-reads:
                read.resp <- state[read.key]
            case write := <-writes:
                state[write.key] = write.val
                write.resp <- true
            }
        }
    }()

    for r := 0; r < 100; r++ {
        go func() {
            for {
                read := &read0p{
                    key:  rand.Intn(5),
                    resp: make(chan int),
                }
                reads <- read
                fmt.Println("<-read.resp:", <-read.resp)
                atomic.AddInt64(&ops, 1)
            }
        }()
    }

    for w := 0; w < 10; w++ {
        go func() {
            for {
                write := &write0p{
                    key:  rand.Intn(5),
                    val:  rand.Intn(100),
                    resp: make(chan bool),
                }
                writes <- write
                <-write.resp
                atomic.AddInt64(&ops, 1)
            }
        }()
    }

    time.Sleep(time.Second)

    opsFinal := atomic.LoadInt64(&ops)
    fmt.Println("ops:", opsFinal)
}
ops: 329696

总结 :

  1 : atomic.AddInt64 原子性的增加一个值

时间: 2024-09-30 06:26:47

statefule goroutines _ golang的相关文章

goroutines _ golang

A goroutine is a loghtweight thread of execution package main import ( "fmt" ) func f(form string) { for i := 0; i < 3; i++ { fmt.Println(form, ";", i) } } func main() { f("direct") go f("goroutine") go func(msg

errors _ golang

In Go it's idiomatic to communicate errors via an explicit, separate return value. this constrasts errors via an explicit, separate return value. This constrasts with the exceptions used in languages like Java and Ruby and the overloaded single resul

multiple return values _ golang

Go has built-in support for multiple return values. This feature is used often in idiomatic Go, for example to return both result and error values from a function package main import ( "fmt" ) func vals() (int, int) { return 3, 7 } func main() {

variadic function _ golang

Variadic functions can be called with any number of trailing arguments. For example, fmt.Println is a common variadic function package main import ( "fmt" ) func sum(nums ...int) { fmt.Println(nums, " ") total := 0 for _, num := range

channel synchronization _ golang

we can use channels to sychronize execution across goroutines. Here's an example of using a blocking receive to to wait for a goroutine to finsh package main import ( "fmt" "time" ) func worker(done chan bool) { fmt.Println("worki

channel _ golang

Channels are the pipes that connect concurrent goroutines. You can send values into channels from one goroutine andreceive those values into another goroutine package main import ( "fmt" ) func main() { messages := make(chan string) go func() {

workerPool _ golang

In this example we'll look at how to implement a worker pool using goroutines and channels package main import ( "fmt" "time" ) func worker(id int, jobs <-chan int, result chan<- int) { for j := range jobs { fmt.Println("wor

if else _ golang

if else 在 golang package main import ( "fmt" ) func main() { if 7%2 == 0 { fmt.Println("7 is even") } else { fmt.Println("7 is odd") } if 8%4 == 0 { fmt.Println("8 is divisible by 4") } if num := 9; num < 0 { fmt

for _ golang

for 是 golang 唯一的 looping 结构, package main import ( "fmt" ) func main() { i := 1 for i <= 3 { fmt.Println(i) i += 1 } for j := 7; j <= 9; j++ { fmt.Println(j) } for { fmt.Println("loop") break } } 1 2 3 7 8 9 loop 总结 : 对于这个, 额, 我觉