• Как создать переменую областью видимости пакета,чтобы не видели другие горутины и без их блокировки?

    EvgenyMamonov
    @EvgenyMamonov Куратор тега Go
    Senior software developer, system architect
    Можно сделать что-то тапа такого.
    Реализация не очень красивая, но, думаю, это даст вам понимание в каком направлении можно двигаться.
    package pkg2
    import "fmt"
    
    type Pkg2 struct {
         str2 []string
    }
    
    func New() *Pkg2 {
        return &Pkg2{
            str2: []string{},
        }
    }
    
    func (p *Pkg2) Test(str string){
        p.str2 = append(p.str2, str)
        fmt.Printf("str:%v %v \n", str, p.str2)
    }


    package main
    
    import (
      "sync"
      "pkg2"
    )
    var wg sync.WaitGroup
    
    func main() {
      text:=[]string{"a1", "a2", "a3", "a4", "a5"}
      for i,str:=range text{
        wg.Add(1)
        p := pkg2.New()
        go start(str, p)
      }
      wg.Wait()
    }
    
    func start(str string, p *pkg2.Pkg2){
        p.Test(str)
        wg.Done()
    }
    Ответ написан
    3 комментария
  • Почему Go с горутинами работает на одном ядре?

    EvgenyMamonov
    @EvgenyMamonov Куратор тега Go
    Senior software developer, system architect
    Горутины выполняются на разных процессорах как и должны, у вас четвёртое число слишком большое, все горутины завершают выполнение, а одна продолжает работать. По этому и создаётся впечатление, что они все работают на одном ядре.

    Чтобы в этом убедиться добавим два fmt.Printf, чтобы получилось вот так
    package main
    
    import (
        "fmt"
        "runtime"
        "sync"
    )
    
    var wg sync.WaitGroup
    
    func main() {
        runtime.GOMAXPROCS(8)
        arr := []int{1343434, 1343434300, 234343400, 334343434000, 400434340, 203434340, 4232, 23545, 15535, 353535, 33434434, 5334345, 3533434345, 3535}
        for idx, el := range arr {
            wg.Add(1)
            go test(el, idx)
        }
        wg.Wait()
    }
    
    func test(el int, idx int) {
        fmt.Printf("%d started: %d\n", idx, el)
        for i := 0; i < el; i++ {
            el = el - 1
        }
        fmt.Printf("%d completed: %d\n", idx, el)
        defer wg.Done()
    }


    Вывод будет примерно таким
    4 started: 400434340
    8 started: 15535
    8 completed: 7767
    13 started: 3535
    13 completed: 1767
    6 started: 4232
    6 completed: 2116
    10 started: 33434434
    3 started: 334343434000
    7 started: 23545
    7 completed: 11772
    5 started: 203434340
    12 started: 3533434345
    11 started: 5334345
    2 started: 234343400
    1 started: 1343434300
    11 completed: 2667172
    9 started: 353535
    9 completed: 176767
    0 started: 1343434
    0 completed: 671717
    10 completed: 16717217
    5 completed: 101717170
    4 completed: 200217170
    2 completed: 117171700
    1 completed: 671717150
    12 completed: 1766717172

    При внимательном просмотре станет видно, что нет записи 3 completed.

    меняю элементы с индексами 4 и 5 на такие же числа 334343434000, 334343434000, т.е. делаем чтобы все горутины отработали, но чтобы 3 осталось, т.е. вот так

    arr := []int{1343434, 1343434300, 234343400, 334343434000, 334343434000, 334343434000, 4232, 23545, 15535, 353535, 33434434, 5334345, 3533434345, 3535}


    Запускаем заново и видим, что теперь 3 ядра отлично загружены
    %Cpu0  :  0.3 us,  1.0 sy,  0.0 ni, 98.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
    %Cpu1  :100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
    %Cpu2  :  1.7 us,  0.7 sy,  0.0 ni, 97.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
    %Cpu3  :  1.6 us,  2.9 sy,  0.0 ni, 95.5 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
    %Cpu4  :100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
    %Cpu5  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
    %Cpu6  :100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
    %Cpu7  :  5.6 us,  1.0 sy,  0.0 ni, 93.4 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
    Ответ написан
    Комментировать