Maison  >  Article  >  développement back-end  >  Analyse détaillée du modèle de planification de coroutines des fonctions Golang

Analyse détaillée du modèle de planification de coroutines des fonctions Golang

WBOY
WBOYoriginal
2023-05-16 08:31:581477parcourir

Golang (également connu sous le nom de langage Go) est un langage de programmation basé sur le langage C ces dernières années, il a attiré beaucoup d'attention et est largement utilisé par les développeurs. L'objectif de conception de Golang est d'améliorer la lisibilité, la maintenabilité, la concurrence et les performances du code. Parmi eux, la concurrence de Golang est l'un de ses plus grands points forts. Il utilise le modèle informatique Goroutine. Cet article procédera à une analyse détaillée du modèle de planification de coroutines dans Golang.

1. Introduction à Goroutine

Dans le langage Golang, les coroutines sont des threads légers qui s'exécutent dans le même espace d'adressage et peuvent partager des données dans le même processus. La coroutine de Golang s'appelle Goroutine, qui est gérée par l'environnement d'exécution du langage Go. Elle peut créer un grand nombre de coroutines en très peu de temps et planifier automatiquement l'exécution des coroutines.

2. Création et destruction de Goroutine

En langage Golang, vous pouvez créer une nouvelle coroutine via le mot-clé go et démarrer l'exécution d'une fonction :

go func () {
    // do something
}()

Dans cet exemple, une nouvelle coroutine est démarrée via le mot-clé go Execution de fonction anonyme (func(){}), l'exécution de cette fonction sera effectuée dans une nouvelle coroutine. Dans Golang, le nombre de coroutines est géré par l'environnement d'exécution, ce qui signifie que nous n'avons pas besoin de créer ou de détruire manuellement une coroutine. Lorsqu'une coroutine termine son exécution, l'environnement d'exécution la détruit automatiquement. func(){})的执行,该函数的执行将在一个新的协程中进行。在Golang中,协程的数量由运行时环境进行管理,这意味着我们不需要手动创建或销毁一个协程。当一个协程执行完成时,运行时环境会自动将其销毁。

三、Goroutine的调度模型

Golang的协程采用了M:N的调度模型。其中M表示操作系统的物理线程,N表示Goroutine的数量。M:N模型中的M线程通过调度器(scheduler)协调N个Goroutine的执行。Golang的运行时环境会根据系统的实际情况创建足够的M线程,以确保可以在不同的处理器上并发执行多个协程。这也就是说,Golang的协程可以实现真正的并发,而不是在不同的时间片间隔内交替运行。

Golang的调度器有三种类型:系统调度器(system scheduler)、用户级别调度器(user-level scheduler)和网络调度器(network scheduler)。其中系统调度器是Golang运行时环境的一部分,它负责将协程分配给M线程,并负责管理系统级别的调度。用户级别调度器运行于用户代码的上下文中,负责在一段时间内轮流执行不同的Goroutine。网络调度器用于处理I/O操作,它会将I/O操作转移到一个专用的M线程上,从而不会在其他协程的执行中影响I/O的处理。

在Goroutine的调度模型中,Golang会在用户代码执行时进行抢占式调度(preemptive scheduling)。这意味着Golang的调度器会在某个时刻强制停止正在执行的Goroutine,并让另一个等待执行的Goroutine运行。这种调度模式可以保证公平性,从而避免某个协程一直占用CPU资源。

四、Goroutine的阻塞和唤醒

在Golang中,协程可以通过chan(channel)来进行通信。chan是一种可以在不同协程间进行通信的数据结构,它可以使一个协程阻塞,直到另一个协程向该chan发送一个消息(通过<-符号实现)或者接收消息(通过chanName := <-chan

3. Le modèle de planification de Goroutine

La coroutine de Golang adopte le modèle de planification M:N. Où M représente le thread physique du système d'exploitation et N représente le nombre de Goroutines. Le thread M dans le modèle M:N coordonne l'exécution de N Goroutines via le planificateur. L'environnement d'exécution de Golang créera suffisamment de threads M en fonction de la situation réelle du système pour garantir que plusieurs coroutines peuvent être exécutées simultanément sur différents processeurs. Cela signifie que les coroutines de Golang peuvent atteindre une véritable concurrence au lieu de s'exécuter alternativement à différents intervalles de temps.

Golang propose trois types de planificateurs : le planificateur système, le planificateur au niveau de l'utilisateur et le planificateur réseau. Le planificateur système fait partie de l'environnement d'exécution Golang. Il est responsable de l'allocation des coroutines aux threads M et de la gestion de la planification au niveau du système. Le planificateur au niveau de l'utilisateur s'exécute dans le contexte du code utilisateur et est responsable de l'exécution successive de différentes Goroutines sur une période donnée. Le planificateur réseau est utilisé pour traiter les opérations d'E/S. Il transférera les opérations d'E/S vers un thread M dédié afin qu'il n'affecte pas le traitement des E/S dans l'exécution d'autres coroutines. 🎜🎜Dans le modèle de planification Goroutine, Golang effectuera une planification préemptive lorsque le code utilisateur est exécuté. Cela signifie que le planificateur de Golang arrêtera de force l'exécution de Goroutine à un moment donné et laissera un autre Goroutine en attente d'exécution s'exécuter. Ce mode de planification peut garantir l'équité et empêcher une certaine coroutine d'occuper les ressources CPU à tout moment. 🎜🎜4. Blocage et réveil de Goroutine🎜🎜Dans Golang, les coroutines peuvent communiquer via chan (canal). chan est une structure de données qui peut communiquer entre différentes coroutines. Elle peut bloquer une coroutine jusqu'à ce qu'une autre coroutine envoie un message au chan (implémenté via le symbole <-) ou reçoit des messages (sous la forme de chanName := <-chan). Lorsqu'une coroutine est bloquée sur chan, le planificateur de Golang arrêtera l'exécution de la coroutine et la transférera vers la file d'attente réactivable. Lorsque le canal de réception de la coroutine reçoit le message et poursuit l'exécution, le planificateur de Golang parcourra la file d'attente réactivable pour obtenir la coroutine et la restaurer dans la file d'attente d'exécution. 🎜🎜5. Résumé🎜🎜La coroutine de Golang est l'un de ses plus grands points forts. Elle adopte le modèle de planification M:N, qui peut obtenir de très bonnes performances dans des scénarios de concurrence réels. Dans le même temps, lorsque vous utilisez des coroutines, vous devez également faire attention aux méthodes de communication entre les coroutines et au mécanisme de blocage du réveil. Lors de l'utilisation de coroutines, des problèmes tels que les blocages et la famine doivent être évités. Par conséquent, lorsque vous utilisez des coroutines Golang, vous devez bien comprendre le mécanisme de planification qui les sous-tend pour garantir la stabilité et les performances du code. 🎜

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