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

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

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

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

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("用時:%ds\n", time.Now().Unix() - starTime)
}

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

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

這種串行處理遇到IO阻塞時,弊端就是太費時間了

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

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

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é)果, 通過管道把數(shù)據(jù)傳遞過來,類似于單一訂閱功能吧
    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) // 批處理 信號量+1
        go goProcess(item, &resChang, taskWG)
    }
    taskWG.Wait()// 這里阻塞,等待所有處理執(zhí)行完畢, 才接著運行下去
    close(resChang)// 已經(jīng)處理完畢后就關(guān)閉處理傳輸通道
    wg.Wait() // 這是阻塞 等待處理收集完畢, 才接著運行去
    // 打印批處理收集的處理結(jié)果
    for _, i := range res {
        fmt.Printf("%s", i)
    }
    fmt.Printf("用時:%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阻塞會在這里阻塞一些時間,而這些io可能是網(wǎng)絡(luò)io也可能是磁盤io等,才會接著運行下去
    res := fmt.Sprintf("任務(wù):%s 處理完畢\n", task.Name)
    defer func() {
        *resChan <- res // 把處理結(jié)果傳出去
        taskWG.Done() // 批處理信號量-1 來報告處理完畢
    }()
}

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

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

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

相關(guān)文章

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

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

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

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

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

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

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

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

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

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

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

    詳解Golang如何在編譯時注入版本信息

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

    Golang中的路由使用詳解

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

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

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

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

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

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

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

最新評論