首頁 > 後端開發 > Golang > golang實作並行

golang實作並行

WBOY
發布: 2023-05-21 19:12:36
原創
624 人瀏覽過

隨著大數據、人工智慧等技術的快速發展,對於高效能與高並發的需求也越來越高。在這個背景下,golang作為一門高並發、高效能的程式語言,備受歡迎。其中,golang的平行特性是其區別於其他語言的重要特徵之一。本篇文章主要探討如何在golang中實現並行,以及並行帶來的效能提升。

一、並行概述

並行是指多個任務同時進行,它並不是指同時執行多個任務。在單一CPU上,在一個瞬間是只能執行一個指令,但是每個指令的執行時間很短,CPU透過快速的輪換來完成從使用者的角度看來的多任務。這種快速輪換導致任務的切換時間變得很短,看起來就像是多任務在同時進行一樣,這就是並行。

在實際應用中,我們通常會使用平行技術來處理那些高並發、高密度的業務場景,透過利用多核心CPU的特性,將任務分配到多個核心上同時執行,提高執行效率。而在golang中,goroutine被稱為輕量級線程,它比線程更加輕量級和高效,而且開啟一個goroutine只需要很少的開銷。因此,golang天生適合用於實現並行操作。

二、goroutine並行

在golang中,我們可以透過goroutine來實現並行操作。 goroutine是一種輕量級線程,它是由golang運行時系統所管理的,並且不會像作業系統線程那樣耗費很多的內存,因此我們可以同時啟動許多goroutine,減少任務的等待時間,提高程式運行效率。下面我們來看看如何開啟goroutine。

1.定義goroutine

在golang中定義goroutine的方式非常簡單,只需要在需要獨立執行的函數體前加上關鍵字go即可。例如:

go func() {
    fmt.Println("Hello, goroutine!")
}()
登入後複製

2.啟動goroutine

啟動goroutine非常簡單,只需要呼叫函數即可。例如:

func main() {
    go func() {
        fmt.Println("Hello, goroutine!")
    }()
    fmt.Println("Hello, main!")
    time.Sleep(time.Second)
}
登入後複製

上面的程式碼中,我們啟動了一個goroutine去列印一句話,同時主函數繼續列印自己的話,並且暫停1秒。此時我們運行程式就會看到,主函數和goroutine會交替印出Hello, main!和Hello, goroutine!,證明了兩個函數在不同的goroutine中並行執行。

3.通道

通道(Channel)是golang提供的一種線程間通訊機制,它的作用就是在goroutine之間傳遞資料。一個通道有兩個端點,分別是發送和接收端。我們可以透過關鍵字make來建立一個通道,然後利用<-來進行資料的傳遞。例如:

func goroutineFunc(c chan int) {
    c <- 1
}

func main() {
    c := make(chan int)
    go goroutineFunc(c)
    result := <-c
    fmt.Println(result)
}
登入後複製

上面的程式碼中,我們在啟動goroutine的同時也創建了一個通道c,然後在goroutine中用c <- 1向通道中寫入1,最後透過result := <-c來讀取資料。這種方式可以在不同goroutine中進行資料的交換,實現大規模並行操作。

三、平行計算

如果我們要進行並行計算,需要將計算任務分配到不同的goroutine中執行,並透過通道進行資料的交換。下面我們透過範例程式碼來示範如何用golang實作並行計算。

1.並行計算pi值

func pi(n int) float64 {
    ch := make(chan float64)
    for i := 0; i < n; i++ {
        go func(start, end int) {
            sum := 0.0
            for j := start; j < end; j++ {
                x := (float64(j) + 0.5) / float64(n)
                sum += 4.0 / (1.0 + x*x)
            }
            ch <- sum
        }(i*n/n, (i+1)*n/n)
    }
    result := 0.0
    for i := 0; i < n; i++ {
        result += <-ch
    }
    return result / float64(n)
}

func main() {
    fmt.Println(pi(10000))
}
登入後複製

在上述程式碼中,我們首先建立了一個長度為n的通道ch,然後使用n個goroutine進行計算,將計算結果寫入通道中。最後,我們從通道中讀取所有結果的和,再計算π值。透過並行計算,我們能夠大幅提高計算速度。

2.並行計算矩陣乘法

func MatrixMul(a, b [][]int) [][]int {
    m, n, p := len(a), len(a[0]), len(b[0])
    c := make([][]int, m)
    for i := 0; i < m; i++ {
        c[i] = make([]int, p)
    }

    ch := make(chan int)
    for i := 0; i < m; i++ {
        for j := 0; j < p; j++ {
            go func(x, y int) {
                sum := 0
                for k := 0; k < n; k++ {
                    sum += a[x][k] * b[k][y]
                }
                ch <- sum
            }(i, j)
        }
    }

    for i := 0; i < m; i++ {
        for j := 0; j < p; j++ {
            c[i][j] = <-ch
        }
    }

    return c
}

func main() {
    a := [][]int{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}
    b := [][]int{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}
    fmt.Println(MatrixMul(a, b))
}
登入後複製

在上述程式碼中,我們使用goroutine來並行計算矩陣的乘積。將計算任務指派到goroutine中,然後透過通道進行資料交換。最後我們從通道中讀取所有結果,組成乘積矩陣。透過並行計算,我們能夠提高計算速度並降低計算成本。

總結

本文主要介紹如何在golang中利用goroutine實作並行計算,以及goroutine和通道的使用方法。透過平行計算,我們能夠將計算任務分配到多個goroutine上,提高程式運行效率,適用於處理高並發、高密度的業務場景。而golang內建的goroutine和通道機制,讓並行操作相對於其他語言來說更加輕鬆和有效率。

以上是golang實作並行的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板