为了账号安全,请及时绑定邮箱和手机立即绑定

坚持 Go 并发

坚持 Go 并发

Go
蝴蝶不菲 2021-10-04 16:08:08
我似乎无法弄清楚接下来要做什么。我的目标是使用图像包中的 SubImage 函数从原始图像创建所有子图像的数组。我能够在 imageSplit() 函数中对图像进行分区,并通过通道传递给 imageReceiver() 函数。我实际上在函数 imageReceiver() 中接收数据,但我不知道如何附加到数组并在从 imageSplit() 函数接收所有图像后使用它。// Partitions Imagefunc 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 imgfunc 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 channelfunc imageReceiver(imgChan chan image.Image) {    img := <-imgChan    spew.Dump(img.Bounds())}我想创建一个全局数组 image.Image 但我不确定这是否是“保存”所有子图像的正确方法。我想这有点令人困惑的原因是因为这是我第一次在 Go 中使用并发。谢谢你的帮助 :)
查看完整描述

1 回答

?
弑天下

TA贡献1818条经验 获得超8个赞

有几种方法可以做到这一点,但我想说你的基本问题是你的接收器不进行聚合,如果你改变了它,它就不会是线程安全的。


修改接收器以进行聚合的简单选择是Image在循环之前分配一个数组并将指向它的指针传递给接收器方法,然后在读取通道时只使用 append。但是你会有一堆不同的 goroutines 争夺对同一个数组的访问。所以真的,你不希望聚合是多线程的。如果是,您需要锁定机制才能写入集合。


相反,您想在循环之后阻塞。最简单的方法就是在循环之后将接收器的主体放在那里内联;


imgs := []image.Image{}

img := <-imgChan

imgs = append(imgs, img)

spew.Dump(img.Bounds())

问题是在现实世界中,然后您的软件会在该线路上阻塞并且没有响应(无法死亡或退出或任何事情),因此您通常会使用频道选择,其中至少有 2 个频道/案例,一个中止该信道的呼叫方Partition是否需要退出并从接收的情况下可以使用将其杀死imgChan。那看起来更像这样;


imgs := []image.Image{}


select {

    case img := <-imgChan

         imgs = append(imgs, img)

         spew.Dump(img.Bounds())

    case _ := <-abortChan:

        return MyCustomError();

    }

这使得你的聚合不是并发的,只有产生我个人认为是更好设计的结果的工作。我也可以解释如何锁定你的接收器方法,但我相信你可以找到很多互斥体等的例子。


查看完整回答
反对 回复 2021-10-04
  • 1 回答
  • 0 关注
  • 164 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信