欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

golang的串行處理和并行處理區(qū)別

 更新時(shí)間:2021年07月08日 15:23:22   作者:吳楚衡  
golang對(duì)比其它語(yǔ)言最大的優(yōu)勢(shì)就是并行計(jì)算(一個(gè)go就能實(shí)現(xiàn)并發(fā)),工作中經(jīng)常遇到并發(fā)的場(chǎng)景, 本文主要介紹了golang的串行處理和并行處理,感興趣的可以了解一下

程序運(yùn)算時(shí)往往需要數(shù)據(jù),而數(shù)據(jù)的IO又往往需要時(shí)間傳輸,而常見(jiàn)的串行處理,是一個(gè)任務(wù)處理完成才接著處理新的任務(wù), 其效率低下可想而知。 假如有3個(gè)任務(wù)要處理,而每個(gè)任務(wù)都有一定的阻塞,串行處理大概是這個(gè)樣子:

main.go

package main

import (
    "fmt"
    "time"
)

type Task struct {
    Duration time.Duration
    Name string
}

func main() {
    // 聲明要處理的任務(wù)
    taskList := []Task {
        {
            1,
            "處理1",
        },
        {
            2,
            "處理2",
        },
        {
            3,
            "處理3",
        },
    }
    starTime := time.Now().Unix()
    for _, item := range taskList {
        goProcess(item)
    }
    fmt.Printf("用時(shí):%ds\n", time.Now().Unix() - starTime)
}

/**
 * 進(jìn)行處理
 */
func goProcess(task Task) {
    time.Sleep(time.Second * task.Duration) // 假設(shè)這是io阻塞會(huì)在這里阻塞一些時(shí)間,而這些io可能是網(wǎng)絡(luò)io也可能是磁盤(pán)io等,io完成后才會(huì)接著運(yùn)行下去
    fmt.Printf("任務(wù):%s 處理完畢\n", task.Name)
}

處理打印結(jié)果
任務(wù):處理1 處理完畢
任務(wù):處理2 處理完畢
任務(wù):處理3 處理完畢
用時(shí):6s

這種串行處理遇到IO阻塞時(shí),弊端就是太費(fèi)時(shí)間了

可以看到,程序在計(jì)算時(shí)或許用不到多少時(shí)間反而是IO阻塞占用了大量的時(shí)間。這種占著茅坑不拉屎,外面等著人直跳腳,確實(shí)不太好。而用異步處理則可以跳過(guò)阻塞,達(dá)到避免占坑的情況發(fā)生。

用協(xié)程的話,則可以在阻塞時(shí)先異步執(zhí)行下去而不用等待,等所有協(xié)程都處理結(jié)束,再把處理的結(jié)果匯總起來(lái)就可以了,代碼大概是這樣子:

main.go

package main

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

type Task struct {
    Duration time.Duration
    Name string
}

func main() {
    // 聲明要處理的任務(wù)
    taskList := []Task {
        {
            1,
            "處理1",
        },
        {
            2,
            "處理2",
        },
        {
            3,
            "處理3",
        },
    }
    starTime := time.Now().Unix()
    var res []string //處理結(jié)果收集
    resChang := make(chan string, len(taskList))
    wg := &sync.WaitGroup{}
    // 這里收集異步處理的結(jié)果, 通過(guò)管道把數(shù)據(jù)傳遞過(guò)來(lái),類似于單一訂閱功能吧
    go func() {
        wg.Add(1)
        defer wg.Done() // 通道關(guān)閉后 處理結(jié)果也收集完畢,則觸發(fā) 用于通知下方批處理,處理結(jié)果已經(jīng)收集完畢
        for resItem := range resChang {
            res = append(res, resItem)
        }
    }()
    taskWG := &sync.WaitGroup{}
    for _, item := range taskList {
        taskWG.Add(1) // 批處理 信號(hào)量+1
        go goProcess(item, &resChang, taskWG)
    }
    taskWG.Wait()// 這里阻塞,等待所有處理執(zhí)行完畢, 才接著運(yùn)行下去
    close(resChang)// 已經(jīng)處理完畢后就關(guān)閉處理傳輸通道
    wg.Wait() // 這是阻塞 等待處理收集完畢, 才接著運(yùn)行去
    // 打印批處理收集的處理結(jié)果
    for _, i := range res {
        fmt.Printf("%s", i)
    }
    fmt.Printf("用時(shí):%ds\n", time.Now().Unix() - starTime)
}

/**
 * 進(jìn)行處理
 */
func goProcess(task Task, resChan *chan string, taskWG *sync.WaitGroup) {
    time.Sleep(time.Second * task.Duration) // 假設(shè)這是io阻塞會(huì)在這里阻塞一些時(shí)間,而這些io可能是網(wǎng)絡(luò)io也可能是磁盤(pán)io等,才會(huì)接著運(yùn)行下去
    res := fmt.Sprintf("任務(wù):%s 處理完畢\n", task.Name)
    defer func() {
        *resChan <- res // 把處理結(jié)果傳出去
        taskWG.Done() // 批處理信號(hào)量-1 來(lái)報(bào)告處理完畢
    }()
}

運(yùn)行結(jié)果
任務(wù):處理1 處理完畢
任務(wù):處理2 處理完畢
任務(wù):處理3 處理完畢
用時(shí):3s

相對(duì)于之前的串行,這次的并行有效處理IO的阻塞,相當(dāng)于,串行就是占坑不用的角,并行則不管這些,你不用,先把你踹開(kāi),給有需要的人用先,這樣一腳腳的踹,效率就上一來(lái)了。

到此這篇關(guān)于golang的串行處理和并行處理實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)golang 串行處理和并行處理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go語(yǔ)言中字符串的查找方法小結(jié)

    Go語(yǔ)言中字符串的查找方法小結(jié)

    這篇文章主要介紹了Go語(yǔ)言中字符串的查找方法小結(jié),示例的main函數(shù)都是導(dǎo)入strings包然后使用其中的方法,需要的朋友可以參考下
    2015-10-10
  • 一文詳解go的defer和return的執(zhí)行順序

    一文詳解go的defer和return的執(zhí)行順序

    go的defer和return是golang中的兩個(gè)關(guān)鍵字,return用于返回函數(shù)的返回值,也可以參與一定的流程控制,defer是golang中的延遲調(diào)用,經(jīng)常用于文件流的關(guān)閉,鎖的解鎖操作,本文給大家介紹了go的defer和return的執(zhí)行順序,需要的朋友可以參考下
    2024-07-07
  • Go?實(shí)現(xiàn)?WebSockets和什么是?WebSockets

    Go?實(shí)現(xiàn)?WebSockets和什么是?WebSockets

    這篇文章主要介紹了Go?實(shí)現(xiàn)?WebSockets和什么是?WebSockets,WebSockets?是構(gòu)建實(shí)時(shí)應(yīng)用程序的第一大解決方案,在線游戲、即時(shí)通訊、跟蹤應(yīng)用程序等,下文相關(guān)內(nèi)容介紹需要的小伙伴可以參考一下
    2022-04-04
  • Go語(yǔ)言中循環(huán)語(yǔ)句使用的示例詳解

    Go語(yǔ)言中循環(huán)語(yǔ)句使用的示例詳解

    在不少實(shí)際問(wèn)題中有許多具有規(guī)律性的重復(fù)操作,因此在程序中就需要重復(fù)執(zhí)行某些語(yǔ)句。本文將通過(guò)示例詳細(xì)為大家講講Go語(yǔ)言中的循環(huán)語(yǔ)句,需要的可以參考一下
    2022-04-04
  • 詳解Go語(yǔ)言中iota的應(yīng)用

    詳解Go語(yǔ)言中iota的應(yīng)用

    在本文中,小編將帶著大家深入探討?iota?的神奇力量,包括?iota?的介紹和應(yīng)用場(chǎng)景以及使用技巧和注意事項(xiàng),準(zhǔn)備好了嗎,準(zhǔn)備一杯你最喜歡的飲料或茶,隨著本文一探究竟吧
    2023-07-07
  • 詳解Golang如何在編譯時(shí)注入版本信息

    詳解Golang如何在編譯時(shí)注入版本信息

    這篇文章主要為大家詳細(xì)介紹了Golang如何在編譯時(shí)實(shí)現(xiàn)注入版本信息,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的可以了解一下
    2023-06-06
  • Golang中的路由使用詳解

    Golang中的路由使用詳解

    這篇文章主要介紹了Golang中的路由使用詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-06-06
  • 一文帶你了解如何正確理解和使用Golang中nil

    一文帶你了解如何正確理解和使用Golang中nil

    在?Golang?中,nil?是一個(gè)預(yù)定義的標(biāo)識(shí)符,在不同的上下文環(huán)境中有不同的含義,但通常表示“無(wú)”、“空”或“零值”,本文主要來(lái)帶大家了解下nil的正確使用,需要的可以參考下
    2023-12-12
  • 并發(fā)安全本地化存儲(chǔ)go-cache讀寫(xiě)鎖實(shí)現(xiàn)多協(xié)程并發(fā)訪問(wèn)

    并發(fā)安全本地化存儲(chǔ)go-cache讀寫(xiě)鎖實(shí)現(xiàn)多協(xié)程并發(fā)訪問(wèn)

    這篇文章主要介紹了并發(fā)安全本地化存儲(chǔ)go-cache讀寫(xiě)鎖實(shí)現(xiàn)多協(xié)程并發(fā)訪問(wèn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • 一文帶你理解Go語(yǔ)言中方法的本質(zhì)

    一文帶你理解Go語(yǔ)言中方法的本質(zhì)

    我們知道,Go語(yǔ)言從設(shè)計(jì)伊始,就不支持經(jīng)典的面向?qū)ο笳Z(yǔ)法元素,但?Go?語(yǔ)言仍保留了名為“方法(method)”的語(yǔ)法元素,下面我們就來(lái)帶大家深入了解一下Go語(yǔ)言中的方法吧
    2023-11-11

最新評(píng)論