Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Amalan terbaik untuk pengaturcaraan serentak di Golang: Penerokaan mendalam tentang kaedah pengoptimuman Goroutines

Amalan terbaik untuk pengaturcaraan serentak di Golang: Penerokaan mendalam tentang kaedah pengoptimuman Goroutines

PHPz
PHPzasal
2023-07-17 11:06:041587semak imbas

Amalan terbaik untuk pengaturcaraan serentak di Golang: Penerokaan mendalam kaedah pengoptimuman Goroutines

Pengenalan:
Dengan aplikasi pemproses berbilang teras yang meluas, pengaturcaraan serentak telah menjadi trend pembangunan. Sebagai bahasa mesra pengaturcaraan serentak, Golang memudahkan pengaturcaraan serentak melalui Goroutines (benang ringan) dan Saluran (mekanisme komunikasi). Walau bagaimanapun, untuk memanfaatkan sepenuhnya kelebihan serentak Golang, anda perlu mempunyai pemahaman yang mendalam tentang kaedah pengoptimuman Goroutines. Artikel ini akan meneroka beberapa teknik untuk mengoptimumkan prestasi Goroutines, bersama-sama dengan contoh kod yang sepadan.

1. Elakkan penciptaan dan pemusnahan terlalu banyak Goroutines
Penciptaan dan pemusnahan Goroutines adalah mahal, jadi penciptaan dan pemusnahan terlalu banyak Goroutines harus dielakkan. Apabila membuat Goroutines, anda boleh menggunakan sync.WaitGroup untuk menunggu semua Goroutines menyelesaikan kerja mereka. Kod sampel adalah seperti berikut:

func main() {
    var wg sync.WaitGroup
    
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func() {
            // Do some work
            wg.Done()
        }()
    }
    
    wg.Wait()
    fmt.Println("All Goroutines have finished.")
}

2. Penggunaan komunikasi yang betul antara Goroutines
Golang menyediakan Saluran untuk melaksanakan komunikasi antara Goroutines, tetapi penggunaan Saluran yang tidak betul akan menjejaskan prestasi. Berikut ialah beberapa cadangan untuk mengoptimumkan komunikasi Goroutines:

  1. Elakkan Saluran yang tidak ditimbal: Saluran yang tidak ditimbal akan menyebabkan penyekatan pada penghantar dan penerima Adalah disyorkan untuk menggunakan Saluran yang ditimbal atau menggunakan operasi penghantaran dan penerimaan yang tidak menyekat.
  2. Penghantaran dan penerimaan kelompok: Jika anda perlu menghantar atau menerima sejumlah kecil data dengan kerap, adalah disyorkan untuk menggunakan kepingan atau penimbal untuk operasi kelompok untuk mengurangkan bilangan komunikasi.
func main() {
    // 使用缓冲Channel,提高发送和接收的效率
    ch := make(chan int, 10)
    
    go func() {
        for i := 0; i < 10; i++ {
            ch <- i
        }
        close(ch)
    }()
    
    // 批量接收数据
    var data []int
    for num := range ch {
        data = append(data, num)
    }
    
    fmt.Println(data)
}

3. Kurangkan penggunaan kunci
Apabila berkongsi data antara berbilang Goroutine, kunci sering diperlukan untuk memastikan konsistensi data. Walau bagaimanapun, penggunaan kunci yang berlebihan boleh mewujudkan kesesakan prestasi. Berikut ialah beberapa cara untuk mengurangkan penggunaan kunci:

  1. Gunakan operasi atom: Pakej penyegerakan/atomik Golang menyediakan operasi atom untuk mengelakkan penggunaan kunci. Operasi atom adalah bebas dan tidak memerlukan penguncian memori yang dikongsi. Kod sampel adalah seperti berikut:
func main() {
    var total int32
    
    var wg sync.WaitGroup
    for i := 0; i < 100; i++ {
        wg.Add(1)
        go func() {
            atomic.AddInt32(&total, 1)
            wg.Done()
        }()
    }
    
    wg.Wait()
    
    fmt.Println("Total:", atomic.LoadInt32(&total))
}
  1. Gunakan kunci baca-tulis: Jika berbilang Goroutine ingin melakukan operasi baca, anda boleh menggunakan kunci baca-tulis (sync.RWMutex) untuk mengawal akses kepada data. Kunci baca boleh dipegang oleh berbilang Goroutine pada masa yang sama untuk meningkatkan prestasi serentak. Kod sampel adalah seperti berikut:
func main() {
    var (
        data    map[string]string
        dataRWM sync.RWMutex
    )
    
    // 向data中添加数据的过程
    go func() {
        dataRWM.Lock()
        defer dataRWM.Unlock()
        
        // Add data to data map
    }()
    
    // 获取data的长度
    go func() {
        dataRWM.RLock()
        defer dataRWM.RUnlock()
        
        length := len(data)
        fmt.Println("Length:", length)
    }()
    
    // 其他并发读操作
}

4. Gunakan primitif penyegerakan untuk memastikan keselamatan serentak
Di Golang, selain kunci dan Saluran, primitif penyegerakan lain juga boleh digunakan untuk memastikan keselamatan serentak. Berikut ialah beberapa primitif penyegerakan yang biasa digunakan:

  1. Sekali: Pastikan fungsi tertentu dilaksanakan sekali sahaja.
var once sync.Once

func setup() {
    // Do some setup work
}

func main() {
    once.Do(setup) // 只会执行一次
}
  1. Cond: Pembolehubah keadaan boleh melaksanakan komunikasi antara Goroutines melalui mekanisme menunggu dan pemberitahuan.
var (
    condition   sync.Cond
    isReady     bool
)

func init() {
    condition = *sync.NewCond(&sync.Mutex{})
}

func worker(id int) {
    condition.L.Lock()
    for !isReady {
        condition.Wait()
    }
    condition.L.Unlock()
    
    // Do some work
}

func main() {
    // 创建多个Goroutines
    for i := 0; i < 10; i++ {
        go worker(i)
    }
    
    // 执行某个触发条件的操作
    condition.L.Lock()
    isReady = true
    condition.Broadcast()
    condition.L.Unlock()
}

Kesimpulan:
Artikel ini memperkenalkan beberapa kaedah untuk mengoptimumkan Goroutines, termasuk mengelakkan penciptaan dan pemusnahan Goroutines secara berlebihan, menggunakan komunikasi secara rasional antara Goroutines, mengurangkan penggunaan kunci dan menggunakan primitif penyegerakan untuk memastikan keselamatan serentak. Dengan menggunakan kaedah pengoptimuman ini dengan betul, prestasi dan kecekapan pengaturcaraan serentak di Golang boleh dipertingkatkan. Dalam aplikasi praktikal, adalah perlu untuk memilih strategi pengoptimuman yang sesuai mengikut situasi tertentu. Pada masa yang sama, anda juga perlu memberi perhatian kepada hubungan antara prestasi konkurensi dan kebolehbacaan kod serta kebolehselenggaraan untuk mengelakkan pengoptimuman yang berlebihan.

Atas ialah kandungan terperinci Amalan terbaik untuk pengaturcaraan serentak di Golang: Penerokaan mendalam tentang kaedah pengoptimuman Goroutines. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
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