本文介绍了如何发送工作池中的GO例程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 限时删除!! 我写了一个算法来将图片分解成片段并对其进行操作,但是我现在使用Go例程的方式并不是最优的。 我想将它分成一个工作池,激发例程并让每个工作人员完成一项新工作,直到图像完成。 我把它分成8份: 我在func splitVert 中实现了你在代码示例中表达的垂直拆分,它返回一个可以拆分的函数一个图像在n个垂直部分。 为了做一些实际的工作,我实现了灰色 func是一个处理器,可将像素颜色转换为灰度级(亮度)。 下面是工作代码: / p> 类型MutableImage接口{ image.Image Set(x,y int,c color.Color) 类型处理器func(MutableImage,image.Rectangle) 类型分区程序func(image.Image)[] image.Rectangle func pprocess(i image.Image,concurrency int,part Partitioner,proc Processor)image.Image {m:= image.NewRGBA(i.Bounds()) draw.Draw(m,i .bounds(),i,i.Bounds()。Min,draw.Src) var wg sync.WaitGroup c:= make(chan image.Rectangle,concurrency * 2) for n:= 0; n<并发性; n $ { wg.Add(1) go func(){ for r:= range c { proc(m,r)} $ b $ (b) $($)b $ b $($) $ p $ = b close(c) wg.Wait() return m } func grey(i MutableImage,r image.Rectangle){ for x:= r.Min.X; x for y:= r.Min.Y; y c:= i.At(x,y)r,g,b,_:= c.RGBA()l:= 0.299 * float64(r)+ 0.587 * float64 g)+ 0.114 * float64(b) i.Set(x,y,color.Gray {uint8(l / 256)})} } } func splitVert(c int)分区程序{ return func(i image.Image)[] image.Rectangle {b:= i.Bounds()s:= float64 (b.Dy())/ float64(c) rs:= make([] image.Rectangle,c) for n:= 0; n< C; n ++ {m:= float64(n) x0:= b.Min.X y0:= b.Min.Y + int(0.5 + m * s) x1 := b.Max.X y1:= b.Min.Y + int(0.5+(m + 1)* s)如果n y1-- } rs [n] = image.Rect(x0,y0,x1,y1)} 返回rs func main(){i,err:= jpeg.Decode(os.Stdin) if err!= nil { log.Fatalf(解码图像:%v,err)} o:= pprocess(i,runtime.NumCPU(),splitVert(8),gray) err = jpeg .Encode(os.Stdout,o,nil) if err!= nil { log.Fatalf(encoding image:%v,err)} } im writing an algorithm to break down an image into segments and manipulate it, however the way im currently using Go routines isn't quite optimal.I'd like to split it into a worker pool, firing off routines and having each worker take a new job until the image is completed.I have it split into 8 as such: var bounds = img.Bounds() var halfHeight = bounds.Max.Y / 2 var eighthOne = halfHeight / 4 var eighthTwo = eighthOne + eighthOne var eighthThree = eighthOne + eighthTwo var eighthFive = halfHeight + eighthOne var eighthSix = halfHeight + eighthTwo var eighthSeven = halfHeight + eighthThree elapsed := time.Now() go Threshold(pic, c2, 0, eighthOne) go Threshold(pic, c5, eighthOne, eighthTwo) go Threshold(pic, c6, eighthTwo, eighthThree) go Threshold(pic, c7, eighthThree, halfHeight) go Threshold(pic, c8, halfHeight, eighthFive) go Threshold(pic, c9, eighthFive, eighthSix) go Threshold(pic, c10, eighthSix, eighthSeven) go Threshold(pic, c11, eighthSeven, bounds.Max.Y)From which i then fire off Go routines one after another, how can i optimise this into a worker system?Thanks 解决方案 Here you have a generic pattern for implementing concurrent image processors giving control to the caller over the image partitioning to split the work in n parts and over the concurrency level of the execution (i.e. the number of worker goroutines used for executing the (possibly different) number of processing jobs).See the pprocess func which implements the whole pattern taking a Partitioner and a Processor, the former being a func that takes the job of returning n image partitions to operate on, and the latter being a func which will be used for processing each partition.I implemented the vertical splitting you expressed in your code example in the func splitVert which returns a function which can split an image in n vertical sections.For doing some actual work I implemented the gray func which is a Processor that transform pixel colors to gray levels (luminance).Here's the working code:type MutableImage interface { image.Image Set(x, y int, c color.Color)}type Processor func(MutableImage, image.Rectangle)type Partitioner func(image.Image) []image.Rectanglefunc pprocess(i image.Image, concurrency int, part Partitioner, proc Processor) image.Image { m := image.NewRGBA(i.Bounds()) draw.Draw(m, i.Bounds(), i, i.Bounds().Min, draw.Src) var wg sync.WaitGroup c := make(chan image.Rectangle, concurrency*2) for n := 0; n < concurrency; n++ { wg.Add(1) go func() { for r := range c { proc(m, r) } wg.Done() }() } for _, p := range part(i) { c <- p } close(c) wg.Wait() return m}func gray(i MutableImage, r image.Rectangle) { for x := r.Min.X; x <= r.Max.X; x++ { for y := r.Min.Y; y <= r.Max.Y; y++ { c := i.At(x, y) r, g, b, _ := c.RGBA() l := 0.299*float64(r) + 0.587*float64(g) + 0.114*float64(b) i.Set(x, y, color.Gray{uint8(l / 256)}) } }}func splitVert(c int) Partitioner { return func(i image.Image) []image.Rectangle { b := i.Bounds() s := float64(b.Dy()) / float64(c) rs := make([]image.Rectangle, c) for n := 0; n < c; n++ { m := float64(n) x0 := b.Min.X y0 := b.Min.Y + int(0.5+m*s) x1 := b.Max.X y1 := b.Min.Y + int(0.5+(m+1)*s) if n < c-1 { y1-- } rs[n] = image.Rect(x0, y0, x1, y1) } return rs }}func main() { i, err := jpeg.Decode(os.Stdin) if err != nil { log.Fatalf("decoding image: %v", err) } o := pprocess(i, runtime.NumCPU(), splitVert(8), gray) err = jpeg.Encode(os.Stdout, o, nil) if err != nil { log.Fatalf("encoding image: %v", err) }} 这篇关于如何发送工作池中的GO例程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 1403页,肝出来的..
09-07 02:56