从多个goroutine访问单个数组

问题描述 投票:0回答:1

我现在正在学习 Go,有一个实际的目的。我需要编写一个程序,在其中需要处理包含数百万个浮点值的数组。在 C++ 中,通过创建指针并在多个处理线程之间划分所有元素的索引,可以轻松解决此任务。

例如,我有一个数组

[x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
。 线程号 1 将获取 0-1 的区域,线程号 2 将获取 2-3 的区域,依此类推。但仅限于数百万的规模,并且线程将是例如16/32/64。与 CUDA 中的原理大致相同。

Go 中是否可以做类似的事情? 谢谢!

演示代码:

import "fmt"
 
func main() {
   
    var numbers [10000000]float64= [10000000]float64{}
    //prepare numbers 

    f:= func(first int, last int){
      //magic is here (read/write)
    }
    
    go f(0, 999999) 
    go f(1000000, 1999999)
    and so on...

}

我才刚刚开始学习

multithreading go goroutine
1个回答
0
投票

是的,你可以做到。这是一种方法,工作人员不传递固定范围,而是进行自己的迭代。请注意使用 sync.WaitGroup 来确保 main 等待所有工作线程完成。

package main

import (
    "fmt"
    "sync"
)

func main() {
    const num_workers = 3
    var numbers = []int{1, 3, 5, 9, 12, 14, 15, 16, 17, 20, 22, 100, 101, 103, 99, 55, 1039, 938}

    var wg sync.WaitGroup

    for i := 0; i < num_workers; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()

            for j := i; j < len(numbers); j += num_workers {
                fmt.Printf("worker: %d, input: %d\n", i, numbers[j])
            }
        }()
    }

    wg.Wait()
}

示范.

但是 Go 中更惯用的方式是使用通道。工作人员根据需要从频道中提取号码。

package main

import (
    "fmt"
    "sync"
)

func main() {
    const num_workers = 3
    var numbers = []int{1, 3, 5, 9, 12, 14, 15, 16, 17, 20, 22, 100, 101, 103, 99, 55, 1039, 938}

    inputs := make(chan int)

    var wg sync.WaitGroup

    for i := 0; i < num_workers; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()

            for input := range inputs {
                fmt.Printf("worker: %d, input: %d\n", i, input)
            }
        }()
    }

    // main feeds the numbers into the channel.
    for _, num := range numbers {
        inputs <- num
    }
    close(inputs)
    wg.Wait()
}

这支持不断变化的工人数量,工人可以按照自己的节奏前进。这些数字不需要被放入内存中,通道可以从流中馈送。

示范

© www.soinside.com 2019 - 2024. All rights reserved.