簡體   English   中英

陷入Go並發

[英]Stuck with Go concurrency

我似乎無法弄清楚下一步該怎么做。 我的目標是使用圖像包中的SubImage函數創建原始圖像中所有子圖像的數組。 我能夠在imageSplit()函數中對圖像進行分區,並通過通道傳遞給imageReceiver()函數。

我實際上是在imageReceiver()函數中接收數據的,但是我不知道如何在從imageSplit()函數接收所有圖像之后追加到數組並使用它。

// Partitions Image
func Partition(src image.Image) []image.Image {

    newImg := image.NewNRGBA64(src.Bounds())

    r := newImg.Rect
    dx, dy := r.Dx(), r.Dy()

   // partitionNum
   pNum := 3

    // partition x
    px, py := (dx / pNum), (dy / pNum)

    imgChan := make(chan image.Image)
    imgStorage := make([]image.Image, 0)

    for i := 1; i < pNum; i++ {
        for j := 1; j < pNum; j++ {
            startX, startY := ((px * i) - px), ((py * j) - py)
            endX, endY := (px * i), (py * j)

            go imageSplit(imgChan, newImg, startX, startY, endX, endY)
            go imageReceiver(imgChan)
        }
    }

    return imgStorage

}

// Creates sub-images of img
func imageSplit(imgChan chan image.Image, img *image.NRGBA64, startX, startY, endX, endY int) {
    r := image.Rect(startX, startY, endX, endY)
    subImg := img.SubImage(r)

    imgChan <- subImg
}

// Receive sub-image from channel
func imageReceiver(imgChan chan image.Image) {
    img := <-imgChan
    spew.Dump(img.Bounds())
}

我曾想創建一個image.Image的全局數組,但是我不確定這是否是“保存”所有子圖像的正確方法。

我想這有點令人困惑是因為這是我第一次在Go中使用並發。 謝謝你的幫助 :)

有幾種方法可以實現此目的,但是我要說的基本問題是,接收者不進行聚合,如果您進行了更改,則這樣做不是線程安全的。

修改接收器以進行聚合的簡單選擇是在循環之前分配一個Image數組,然后將指向它的指針傳遞給接收器方法,然后在讀取通道時僅使用append。 但是隨后您將有許多不同的goroutine爭奪對同一數組的訪問權。 所以說真的,您不希望聚合是多線程的。 如果是,則需要一種鎖定機制才能寫入集合。

相反,您想在循環之后阻塞。 最簡單的方法就是在循環之后將接收器的主體直接插入該行。

imgs := []image.Image{}
img := <-imgChan
imgs = append(imgs, img)
spew.Dump(img.Bounds())

問題是在現實世界中,然后您的軟件將在該行上阻塞並且無法響應(無法死掉或退出或發生任何事情),因此通常應使用通道選擇,其中至少有2個通道/案例,如果需要退出,並且imgChan收到的情況下, Partition的調用者可以使用該通道終止它的終止通道。 看起來會更像這樣;

imgs := []image.Image{}

select {
    case img := <-imgChan
         imgs = append(imgs, img)
         spew.Dump(img.Bounds())
    case _ := <-abortChan:
        return MyCustomError();
    }

這樣,您的聚合就不會並發了,只有產生結果的工作才是我個人認為更好的設計。 我也可以解釋如何鎖定您的接收器方法,但是我敢肯定您可以找到很多互斥體實例的例子。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM