douhuan9289 2015-05-05 19:57
浏览 24
已采纳

陷入Go并发

I can't seem to figure out what to do next. My goal is to create an array of all the sub images from the original image using the SubImage function from the image package. I am able to partition an image in the imageSplit() function and pass to imageReceiver() function via a channel.

I actually receive the data in function imageReceiver(), but I don't know how to append to an array and use it after receiving all the images from imageSplit() function.

// 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())
}

I thought of creating a global array of image.Image but I'm unsure if this is the correct way to "save" all the sub images.

I guess the reason this is a bit confusing is because this is the first time I'm working with concurrency in Go. Thanks for any help :)

  • 写回答

1条回答 默认 最新

  • doupao5296 2015-05-05 20:29
    关注

    There are a few options for how you can do this but I would say your basic problem is that your receiver doesn't do aggregation and if you changed it so it did it would not be thread safe.

    The simple choice to modify your receiver to do aggregation would be to allocate an Image array before the loop and pass a pointer to it into the receiver method which would then just use append when it reads of the channel. But then you would have a bunch of different goroutines fighting for access to the same array. So really, you don't want the aggregation to be multithreaded. If it is you need a locking mechanism in order to write to the collection.

    Instead you want to block after the loop. The simplest way to do that would just be to put the body of your receiver right there inline after the loop like;

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

    The problem is in the real world then your software would block on that line and be unresponsive (have no way of dying or exiting or anything) so instead you'd typically use a channel select where you have at least 2 channels/cases, an abort channel that the caller of Partition can use to kill it if it needs to exit and the case that receives from imgChan. That would look a little more like this;

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

    Which make it so your aggregation is not concurrent, only the work to produce the results which I personally think is the better design. I could explain how to lock in your receiver method as well but I'm sure you can find plenty of examples of mutex's ect.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 RPA正常跑,cmd输入cookies跑不出来
  • ¥15 求帮我调试一下freefem代码
  • ¥15 matlab代码解决,怎么运行
  • ¥15 R语言Rstudio突然无法启动
  • ¥15 关于#matlab#的问题:提取2个图像的变量作为另外一个图像像元的移动量,计算新的位置创建新的图像并提取第二个图像的变量到新的图像
  • ¥15 改算法,照着压缩包里边,参考其他代码封装的格式 写到main函数里
  • ¥15 用windows做服务的同志有吗
  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。