K
K
Kairr2021-08-16 19:18:08
go
Kairr, 2021-08-16 19:18:08

How to synchronize goroutines?

I'm just getting started with Go.
Tell me pliz in which direction you can think?
I need the numbers to be displayed in order. This code seems to work, but sometimes it outputs random numbers

package main

import (
  "fmt"
  "sync"
)

func main() {
  var wg sync.WaitGroup
  wg.Add(2)

  num := make(chan string)


  go func() {
    for _, value := range []int{1, 3, 5} {
      num <- "ok"
      fmt.Println(value)
    }
    wg.Done()
  }()

  go func() {
    for _, value := range []int{2, 4, 6} {
      <- num
      fmt.Println(value)
    }
    wg.Done()
  }()

  wg.Wait()
}

Answer the question

In order to leave comments, you need to log in

2 answer(s)
E
Evgeny Mamonov, 2021-08-16
@Kairr

Goroutines can be synchronized/exchanged using channels.
You don't have a very good learning example.
Usually there is a goroutine or several that receive data and write it to the channel and there is a goroutine or several that will read from the channel.
Reader goroutines will receive data from the channel in the order in which they got there.
Closer to reality, the example will look like this.
One goroutine writes data to the channel, and two goroutines take turns fetching data.

package main

import (
    "fmt"
    "sync"
    "time"
)

func main() {
    var wg sync.WaitGroup

    num := make(chan int, 1000) // 1000 - размер буффера канала

    wg.Add(1)
    go func() {
        for i := 0; i < 1000; i++ {
            num <- i
            fmt.Printf("write to channel: %d\n", i)
            // задержка нужна только на время теста
            time.Sleep(100 * time.Microsecond)
        }
        close(num)
        wg.Done()
    }()

    wg.Add(1)
    go func() {
        for {
            val, ok := <-num
            if !ok {
                break
            }
            fmt.Printf("goroutine 1 got: %d\n", val)
        }
        wg.Done()
    }()

    wg.Add(1)
    go func() {
        for {
            val, ok := <-num
            if !ok {
                break
            }
            fmt.Printf("goroutine 2 got: %d\n", val)
        }
        wg.Done()
    }()

    wg.Wait()
}

K
Kenit, 2021-08-18
@Kenit

Channels in Go, if simplified, are queues. Goroutines are threads that fight for resources and in general their order of execution can be considered randomly parallel in this example. To output the numbers in order in this case, I would add a mutex-based synchronization primitive that will monitor the order in which the channel is used by the goroutines.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question