首页 > 其他分享 >Go语言的 串行处理 和 并行处理 有什么区别 ?

Go语言的 串行处理 和 并行处理 有什么区别 ?

时间:2022-12-05 09:33:22浏览次数:67  
标签:并行处理 处理 处理完毕 阻塞 串行 io time Go

 

原创 学习与分享 Go语言圈 2022-12-05 08:30 发表于广东 收录于合集#为什么要学Go语言141个 学习与交流:Go语言技术微信群

商务合作加微信:LetsFeng

goland 全家桶激活码,支持所有版本,支持所有系统

链接:http://web.52shizhan.cn/activity/s2abxc

提取码:GJF9B1DK

 

现在就开始你的Go语言学习之旅吧!人生苦短,let’s Go.



 

 

程序运算时往往需要数据,而数据的IO又往往需要时间传输,而常见的串行处理,是一个任务处理完成才接着处理新的任务, 其效率低下可想而知。 

 

假如有3个任务要处理,而每个任务都有一定的阻塞,串行处理大概是这个样子:

main.go

package main

import (
    "fmt"
    "time"
)

type Task struct {
    Duration time.Duration
    Name string
}

func main() {
    // 声明要处理的任务
    taskList := []Task {
        {
            1,
            "处理1",
        },
        {
            2,
            "处理2",
        },
        {
            3,
            "处理3",
        },
    }
    starTime := time.Now().Unix()
    for _, item := range taskList {
        goProcess(item)
    }
    fmt.Printf("用时:%ds\n", time.Now().Unix() - starTime)
}

/**
 * 进行处理
 */
func goProcess(task Task) {
    time.Sleep(time.Second * task.Duration) // 假设这是io阻塞会在这里阻塞一些时间,而这些io可能是网络io也可能是磁盘io等,io完成后才会接着运行下去
    fmt.Printf("任务:%s 处理完毕\n", task.Name)
}

 

处理打印结果
任务:处理1 处理完毕
任务:处理2 处理完毕
任务:处理3 处理完毕
用时:6s

这种串行处理遇到IO阻塞时,弊端就是太费时间了

可以看到,程序在计算时或许用不到多少时间反而是IO阻塞占用了大量的时间。这种占着茅坑不拉屎,外面等着人直跳脚,确实不太好。而用异步处理则可以跳过阻塞,达到避免占坑的情况发生。

 

用协程的话,则可以在阻塞时先异步执行下去而不用等待,等所有协程都处理结束,再把处理的结果汇总起来就可以了,代码大概是这样子:

main.go

package main

import (
    "fmt"
    "sync"
    "time"
)

type Task struct {
    Duration time.Duration
    Name string
}

func main() {
    // 声明要处理的任务
    taskList := []Task {
        {
            1,
            "处理1",
        },
        {
            2,
            "处理2",
        },
        {
            3,
            "处理3",
        },
    }
    starTime := time.Now().Unix()
    var res []string //处理结果收集
    resChang := make(chan string, len(taskList))
    wg := &sync.WaitGroup{}
    // 这里收集异步处理的结果, 通过管道把数据传递过来,类似于单一订阅功能吧
    go func() {
        wg.Add(1)
        defer wg.Done() // 通道关闭后 处理结果也收集完毕,则触发 用于通知下方批处理,处理结果已经收集完毕
        for resItem := range resChang {
            res = append(res, resItem)
        }
    }()
    taskWG := &sync.WaitGroup{}
    for _, item := range taskList {
        taskWG.Add(1) // 批处理 信号量+1
        go goProcess(item, &resChang, taskWG)
    }
    taskWG.Wait()// 这里阻塞,等待所有处理执行完毕, 才接着运行下去
    close(resChang)// 已经处理完毕后就关闭处理传输通道
    wg.Wait() // 这是阻塞 等待处理收集完毕, 才接着运行去
    // 打印批处理收集的处理结果
    for _, i := range res {
        fmt.Printf("%s", i)
    }
    fmt.Printf("用时:%ds\n", time.Now().Unix() - starTime)
}

/**
 * 进行处理
 */
func goProcess(task Task, resChan *chan string, taskWG *sync.WaitGroup) {
    time.Sleep(time.Second * task.Duration) // 假设这是io阻塞会在这里阻塞一些时间,而这些io可能是网络io也可能是磁盘io等,才会接着运行下去
    res := fmt.Sprintf("任务:%s 处理完毕\n", task.Name)
    defer func() {
        *resChan <- res // 把处理结果传出去
        taskWG.Done() // 批处理信号量-1 来报告处理完毕
    }()
}

 

运行结果
任务:处理1 处理完毕
任务:处理2 处理完毕
任务:处理3 处理完毕
用时:3s

相对于之前的串行,这次的并行有效处理IO的阻塞,相当于,串行就是占坑不用的角,并行则不管这些,你不用,先把你踹开,给有需要的人用先,这样一脚脚的踹,效率就上一来了。

 

 

文章首发:https://www.jb51.net/article/216996.htm

 

 

 

 

更多相关Go语言的技术文章或视频教程,请关注本公众号获取并查看,感谢你的支持与信任!

标签:并行处理,处理,处理完毕,阻塞,串行,io,time,Go
From: https://www.cnblogs.com/cheyunhua/p/16951478.html

相关文章

  • go build 报错
    一、gobuild报错D:\redis\RedisEXP-main\cmd>gobuild-oRedisEXPmain.gogo:downloadinggithub.com/axgle/mahoniav0.0.0-20180208002826-3358181d7394go:downlo......
  • go操作Kfaka
    目录1.Kafka介绍1.1.1.Kafka是什么1.1.2.Kafka的特点1.1.3.常用的场景1.1.4.Kafka中包含以下基础概念1.1.5.消息1.1.6.消息格式2.Kafka深层介绍2.1.1.架构介绍2.1......
  • golang的快速排序
    1、什么是快速排序:快速排序是一种分治策略的排序算法,本质上来看,快速排序是对冒泡排序的一种改进,属于交换类的排序算法。是由英国计算机科学家 TonyHoare​ 发明的,该算法......
  • Go-08 Golang中的切片
    packagemainimport"fmt"//Go语言中的切片/* 学习目标 1.为什么要使用切片 2.切片的定义 3.关于nil的认识 4.切片的循环遍历 5.基于数组定义切片 6.切片再切......
  • Golang反射修改变量值
    1.前言前面的随笔Golang反射获取变量类型和值分享了如何通过反射获取变量的类型和值,也就是Golang反射三大定律中的前两个,即从interface{}到反射对象和从反射对象到inter......
  • MongoDB入门
    MongoDB数据库https://www.liuqingzheng.top/db/Mongodb系列/Mongodb快速入门/1MongoDB介绍#MongoDB数据库简单介绍是一个面对文档(document-oriented)的数据库,不......
  • MongoDB 的使用
    MongoDB的使用mongoDB的常见命令使用;MongoDB默认在27017端口上运行;1.常见命令#进入交互终端mongo开启云监控平台//开启云监控平台[公司一般不会允许内部信......
  • MongoDB 介绍及安装
    MongoDB介绍及安装官方文档:https://www.mongodb.com/docs/中文文档:https://www.mongodb.org.cn/操作文档:https://www.qikegu.com/docs/3267mongoDB的生态、理念非常先......
  • Python 使用MongoDB & MongoDB 工具的封装
    Python使用MongoDB补充:操作之前首先在虚拟机或者服务器端启动MongoDB;#重新加载配置,并启动mongodbsudosystemctldaemon-reloadsudosystemctlstartmongod#......
  • Django中使用django_table2如何加一列操作
    要加入列需要自定义一个列,doc中给出如下的例子:>>>fromdjango.utils.safestringimportmark_safe>>>fromdjango.utils.htmlimportescape>>>>>>classImageColu......