Rumah > pembangunan bahagian belakang > Golang > Golang melaksanakan konkurensi

Golang melaksanakan konkurensi

WBOY
Lepaskan: 2023-05-16 09:44:37
asal
1131 orang telah melayarinya

Dengan kemajuan berterusan teknologi komputer, kecekapan pengendalian dan prestasi program moden telah menjadi isu yang semakin penting. Pengaturcaraan serentak ialah cara penting untuk meningkatkan kecekapan dan prestasi menjalankan program. Sebagai bahasa pengaturcaraan yang baru muncul, mekanisme goroutine dan saluran unik golang menjadikan pengaturcaraan serentak lebih mudah dan lebih cekap.

Artikel ini akan memperkenalkan konsep asas pengaturcaraan serentak golang, dan menggunakan beberapa contoh untuk menunjukkan cara menggunakan goroutin dan saluran untuk membina program serentak yang cekap.

1. Apakah itu goroutine

Goroutine ialah benang ringan dalam golang Saiz setiap goroutine hanya kira-kira 2KB, menggunakan memori dan sumber yang sangat sedikit. Selain itu, penjadual golang secara automatik akan memperuntukkan goroutine kepada utas fizikal yang berbeza untuk pelaksanaan, dengan itu mencapai pelaksanaan serentak.

Anda boleh memulakan goroutine melalui kata kunci go, contohnya:

package main

import (
    "fmt"
    "time"
)

func printNums() {
    for i := 0; i < 5; i++ {
        fmt.Println(i)
        time.Sleep(time.Millisecond * 500)
    }
}

func main() {
    // 启动一个goroutine
    go printNums()

    // 继续执行主goroutine
    for i := 0; i < 5; i++ {
        fmt.Println("Hello")
        time.Sleep(time.Millisecond * 500)
    }
}
Salin selepas log masuk

Jalankan atur cara di atas, anda dapat melihat bahawa kedua-dua goroutine secara bergantian mengeluarkan nombor dan Hello, dengan itu mencapai pelaksanaan serentak.

2. Apakah itu saluran

Saluran di Golang ialah struktur data yang digunakan untuk komunikasi dan penyegerakan antara goroutine. Saluran boleh memindahkan data antara berbilang goroutine dan mencapai pertukaran data yang selamat melalui mekanisme penyegerakan saluran. Terdapat dua jenis saluran: buffered dan unbuffered. Hantar dan terima operasi pada blok saluran tidak buffer sehingga operasi terima dan hantar yang sepadan berlaku. Saluran penimbal boleh mengurangkan perbezaan masa antara operasi hantar dan terima pada tahap tertentu.

Berikut ialah contoh penggunaan saluran penimbal:

package main

import (
    "fmt"
    "time"
)

func main() {
    // 创建一个大小为2的带缓冲通道
    ch := make(chan string, 2)

    // 启动两个goroutine
    go func() {
        ch <- "Hello"
        ch <- "World"
    }()
    go func() {
        time.Sleep(time.Second)
        fmt.Println(<-ch)
        fmt.Println(<-ch)
    }()

    // 等待goroutine执行完毕
    time.Sleep(time.Second * 2)
}
Salin selepas log masuk

Dalam contoh di atas, kami mencipta saluran penimbal bersaiz 2. Kemudian dua goroutine dimulakan, satu menghantar dua rentetan ke saluran, dan yang lain menerima dua rentetan dari saluran dan mencetak output. Disebabkan kewujudan penimbal, terdapat perbezaan masa tertentu antara operasi hantar dan terima, tetapi data masih boleh dipindahkan dan disegerakkan melalui saluran.

Selain saluran buffer, golang juga menyokong saluran tidak buffer, yang boleh menjamin penyegerakan antara goroutine dengan lebih tegas.

3. Cara menggunakan goroutine dan saluran untuk mencapai keselarasan

Melalui pengenalan sebelum ini, kita dapat melihat bahawa goroutine dan saluran adalah alat pengaturcaraan serentak yang sangat berguna dalam golang. Di bawah ini kami akan memperkenalkan cara menggunakannya untuk melaksanakan pengaturcaraan serentak melalui beberapa contoh.

1. Muat turun berbilang halaman web secara serentak

Melalui goroutine dan saluran, kami boleh memuat turun berbilang halaman web secara serentak dengan mudah. Contohnya:

package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
    "time"
)

// 下载网页的函数
func download(url string, ch chan<- string) {
    resp, err := http.Get(url)
    if err != nil {
        ch <- fmt.Sprintf("%s error: %v", url, err)
        return
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        ch <- fmt.Sprintf("%s error: %v", url, err)
        return
    }
    ch <- fmt.Sprintf("%s=%d", url, len(body))
}

func main() {
    // 要下载的网页列表
    urls := []string{
        "https://www.baidu.com",
        "https://www.google.com",
        "https://www.github.com",
    }

    // 创建一个无缓冲通道
    ch := make(chan string)

    // 启动多个goroutine下载网页
    for _, url := range urls {
        go download(url, ch)
    }

    // 从通道中读取结果,并打印输出
    for range urls {
        fmt.Println(<-ch)
    }

    // 等待goroutine执行完毕
    time.Sleep(time.Second * 2)
}
Salin selepas log masuk

Dalam contoh di atas, kami menentukan fungsi muat turun untuk memuat turun kandungan web url yang ditentukan dan mengembalikan hasilnya melalui saluran. Kemudian kami memulakan berbilang goroutine melalui gelung for, dan setiap goroutine memanggil fungsi muat turun untuk memuat turun halaman web. Selepas hasil muat turun dikembalikan melalui saluran, ia dibaca dan dicetak dalam goroutine utama. Dengan cara ini, kami boleh memuat turun berbilang halaman web secara serentak dengan mudah dan meningkatkan kecekapan pengendalian dan prestasi program.

2. Memproses berbilang tugas secara serentak

Selain memuat turun halaman web, kami juga boleh menggunakan goroutine dan saluran untuk memproses berbilang tugas secara serentak. Contohnya:

package main

import (
    "fmt"
    "math/rand"
    "time"
)

func worker(id int, jobs <-chan int, results chan<- int) {
    for i := range jobs {
        fmt.Printf("worker %d start job %d
", id, i)
        time.Sleep(time.Duration(rand.Intn(3)) * time.Second)
        fmt.Printf("worker %d finish job %d
", id, i)
        results <- i * 2
    }
}

func main() {
    // 定义要处理的任务列表
    jobCount := 10
    jobs := make(chan int, jobCount)
    for i := 0; i < jobCount; i++ {
        jobs <- i
    }
    close(jobs)

    // 定义结果通道
    results := make(chan int, jobCount)

    // 启动多个goroutine处理任务
    workerCount := 3
    for i := 0; i < workerCount; i++ {
        go worker(i, jobs, results)
    }

    // 从结果通道中读取结果,并打印输出
    for j := 0; j < jobCount; j++ {
        fmt.Println(<-results)
    }

    // 等待goroutine执行完毕
    time.Sleep(time.Second * 2)
}
Salin selepas log masuk

Dalam contoh di atas, kami menentukan fungsi pekerja untuk mensimulasikan pemprosesan tugas yang ditentukan. Kemudian kami memulakan berbilang goroutine melalui gelung for, setiap goroutine membaca tugasan daripada saluran kerja dan memprosesnya. Hasil pemprosesan dikembalikan melalui saluran keputusan. Akhirnya, semua keputusan dibaca dari saluran keputusan dalam goroutine utama dan dicetak. Dengan cara ini, kami boleh memproses berbilang tugas secara serentak dan meningkatkan kecekapan dan prestasi program berjalan dengan mudah.

4. Ringkasan

Artikel ini memperkenalkan konsep asas pengaturcaraan serentak golang, termasuk penggunaan goroutine dan saluran. Melalui pelbagai contoh, kami menunjukkan cara menggunakan goroutin dan saluran untuk membina program serentak yang cekap. Berbanding dengan bahasa pengaturcaraan lain, model pengaturcaraan serentak golang adalah lebih ringkas dan cekap, yang sangat meningkatkan kecekapan dan prestasi program berjalan. Walau bagaimanapun, perlu diingatkan bahawa menulis program serentak yang berkualiti tinggi bukanlah mudah Ia memerlukan pemahaman dan penguasaan yang mendalam tentang mekanisme dan prinsip pengaturcaraan serentak golang.

Atas ialah kandungan terperinci Golang melaksanakan konkurensi. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan