Maison  >  Article  >  développement back-end  >  Gestion et planification des goroutines en programmation concurrente Go

Gestion et planification des goroutines en programmation concurrente Go

PHPz
PHPzoriginal
2024-06-04 16:42:00832parcourir

Goroutine en langage Go peut être géré des manières suivantes : 1. Créer Goroutine : Utilisez le mot-clé "go". 2. Attendez que Goroutine se termine : utilisez WaitGroup. 3. Annulez Goroutine : utilisez context.Context et context.WithCancel. En termes de planification, Go utilise un algorithme de planification préemptive, mais la fonction runtime.Gosched() peut être utilisée pour déclencher une planification coopérative.

Gestion et planification des goroutines en programmation concurrente Go

Gestion et planification de Goroutine dans la programmation simultanée Go

Goroutine est une unité d'exécution simultanée légère dans le langage Go, qui est similaire à une coroutine. Afin de gérer et planifier efficacement les goroutines, améliorant ainsi les performances et la stabilité des programmes concurrents, le langage Go fournit une API riche.

Gestion du cycle de vie de la goroutine

  • Créer une goroutine : Utilisez le mot-clé go pour créer une goroutine, comme indiqué ci-dessous : go 关键字创建 goroutine,如下所示:

    go func() {
    // Goroutine 代码
    }
  • 等待 goroutine 退出:使用 WaitGroup 类型等待所有 goroutine 退出,如下所示:

    var wg sync.WaitGroup
    wg.Add(numOfWorkers)
    
    for i := 0; i < numOfWorkers; i++ {
    go func(i int) {
      // Goroutine 代码
      wg.Done()
    }(i)
    }
    
    wg.Wait()
  • 取消 goroutine:使用 context.Contextcontext.WithCancel 函数取消 goroutine 的执行,如下所示:

    ctx, cancel := context.WithCancel(context.Background())
    
    go func() {
    // Goroutine 代码
    select {
    case <-ctx.Done():
      return
    }
    }
    
    // 取消 goroutine
    cancel()

Goroutine 调度

Go 语言中内置的调度器负责管理和调度 goroutine。它通过以下算法来决定何时启动 goroutine:

  • 抢占式调度:调度器可以打断正在运行的 goroutine,切换到另一个 goroutine 执行。
  • 协作式调度:goroutine 主动让出控制权,交给调度器调度其他 goroutine。

默认情况下,Go 语言使用抢占式调度算法,但对于某些场景,协作式调度更加合适。可以使用 runtime.Gosched()

package main

import "fmt"
import "sync"

func main() {
  // 创建 goroutine 池
  pool := make(chan func())

  // 启动 goroutine 池中的 worker
  for i := 0; i < 10; i++ {
    go func() {
      for {
        // 从池中获取任务
        task := <-pool

        // 执行任务
        task()
      }
    }()
  }

  // 发送任务到池中
  for i := 0; i < 100; i++ {
    pool <- func() {
      fmt.Println("Task", i)
    }
  }

  // 等待任务完成
  var wg sync.WaitGroup
  wg.Add(100)
  for i := 0; i < 100; i++ {
    go func() {
      defer wg.Done()
      <-pool
    }()
  }
  wg.Wait()

  // 关闭池
  close(pool)
}

Attendez que goroutine se termine :

Utilisez WaitGroup attend que toutes les goroutines se terminent, comme indiqué ci-dessous :

rrreee🎜🎜🎜Annuler une goroutine : 🎜Utilisez context.Context et context.WithCancel La fonction annule l'exécution de la goroutine, comme indiqué ci-dessous : 🎜rrreee🎜Goroutine Scheduling🎜🎜Le planificateur intégré au langage Go est responsable de la gestion et de la planification des goroutines. Il utilise l'algorithme suivant pour décider quand démarrer une goroutine : 🎜🎜🎜🎜Planification préemptive : 🎜Le planificateur peut interrompre une goroutine en cours d'exécution et passer à une autre goroutine pour l'exécution. 🎜🎜Planification collaborative : 🎜goroutine abandonne activement le contrôle et le confie au planificateur pour qu'il planifie d'autres goroutines. 🎜Par défaut, le langage Go utilise un algorithme de planification préemptive, mais pour certains scénarios, la planification collaborative est plus appropriée. La planification coopérative peut être déclenchée à l'aide de la fonction runtime.Gosched(). 🎜🎜Cas pratique🎜🎜Ce qui suit est un exemple d'utilisation de goroutine pour traiter des tâches simultanément : 🎜rrreee

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn