ZVVQ代理分享网

golang框架在并行编程方面的优势体现在哪里?(

作者:zvvq博客网
导读go 框架通过内置的并发原语提供强大的并行编程功能,包括 goroutine(轻量级线程)、channel(通信)和锁。这些特性使程序员能够明确且轻松地编写并行代码,同时提高效率和可扩展性

go 架构根据内置的并发原语提供强大的并行编程作用,包含 goroutine(轻量进程)、channel(通讯)和锁。这些特性使程序员可以明确且快速地撰写并行编码,同时提高效率和扩展性。

Go 架构在并行编程上的优势

并发编程在当代APP开发中尤为重要,它允许同时执行多个任务以提高效率。Go 凭借内置的并发售词义,为并行编程提供了强大而易用的特点。

内置的并发原语

Go 关键库提供了一系列并发原语,包含 goroutine(轻量进程)、channel(用以通讯)和锁。这种原语容许程序猿明确和快速地撰写并行编码。

import (

"fmt"

"sync"

"time"

)

func main() {

var wg sync.WaitGroup

for i := 0; i < 10; i++ {

wg.Add(1)

go func(i int) {

fmt.Printf("goroutine %d: sleeping for 1 second ", i)

time.Sleep(1 time.Second)

wg.Done()

}(i)

}

wg.Wait() // 等候全部 goroutine 进行

}

这段代码创立了 10 个 goroutine,每个 goroutine 睡眠 1 秒,然后向主线程发出信号表明已完成。WaitGroup 确保所有 goroutine 完成后再执行。

Channel用以通讯

Channel是Go 中用于 goroutine 中间通信的安全并发的值缓冲区。他们容许程序猿以同歩或异步方式无堵塞地发送和接收数据。

import (

"fmt"

"sync"

)

func main() {

var wg sync.WaitGroup

ch := make(chan int)

wg.Add(1)

go func() {

defer wg.Done()

for i := 0; i < 10; i++ {

ch <- i

}

close(ch) // 关掉 channel 以标示数据发送结束

}()

wg.Add(1)

go func() {

defer wg.Done()

for v := range ch {

fmt.Printf("received value: %d ", v)

}

}()

wg.Wait() // 等候全部 goroutine 进行

}

在这个例子中,goroutine 在 channel 上推送值,而另一个 goroutine 从 channel 接受值。close() 函数用以通告接受者 channel 已关闭,不会再有数据发送。

实战案例 :并行图像处理

Go 在并行计算大批数据时非常高效。下面是一个应用Go 并行计算图像的实例:

import (

"image"

"image/jpeg"

"os"

"sync"

)

func main() {

// 开启文件列表

files, err := os.ReadDir("images")

if err != nil {

panic(err)

}

// 创建一个用于处理图像的 goroutine 池

const numWorkers = 4

pool := make(chan image.Image, numWorkers)

var wg sync.WaitGroup

for _, file := range files {

wg.Add(1)

go func(file string) {

// 开启图象并调整大小

img, err := os.Open("images/" + file)

if err != nil {

panic(err)

}

resizedImg, err := resizeImage(img)

if err != nil {

panic(err)

}

pool <- resizedImg // 将调整大小后的图象放进 channel

wg.Done()

}(file.Name())

}

go func() {

for img := range pool {

// 储存调整大小后的图象

err := saveImageAsJPEG(img, "resized-images/"+file.Name())

if err != nil {

panic(err)

}

}

}()

wg.Wait() // 等候全部 goroutine 进行

}

func resizeImage(r io.Reader) (resizedImg image.Image, err error) {

// 先把文档分析为图像数据

img, err := jpeg.Decode(r)

if err != nil {

return nil, err

}

// 调节图像大小

resizedImg=image.NewRGBA(image.Rect(0,0,img.Bounds().Dx()/2,img.Bounds().Dy()/2))

fory:=0;y

forx:=0;x

p:=yresizedImg.Bounds().Dy()+x

resizedImg.Pix[p4]=img.Pix[(2y+1)img.Bounds().Dx()+(2x+1)4]

resizedImg.Pix[p4+1]=img.Pix[(2y+1)img.Bounds().Dx()+(2x+1)4+1]

resizedImg.Pix[p4+2]=img.Pix[(2y+1)img.Bounds().Dx()+(2x+1)4+2]

resizedImg.Pix[p4+3]=img.Pix[(2y+1)img.Bounds().Dx()+(2x+1)4+3]

}

}

returnresizedImg,nil

}

funcsaveImageAsJPEG(imgimage.Image,fstring)error{

file,err:=os.Create(f)

iferr!=nil{

returnerr

}

err=jpeg.Encode(file,img,&jpeg.Options{

Quality:95,

})

returnerr

}

这一编码应用 goroutine 池并行计算键入目录中的图象。它首先开启图像文件,调节其大小,再将调整大小后的图象放进 channel。另一个 goroutine 从 channel 中载入图象并把它保存到新目录中。

以上就是golang架构在并行编程上的优势体现在哪里?的详细内容,大量请关注其他类似文章!