Maison >développement back-end >Golang >Un article pour vous présenter les bases de la simultanéité du langage Go

Un article pour vous présenter les bases de la simultanéité du langage Go

Go语言进阶学习
Go语言进阶学习avant
2023-07-21 10:33:26934parcourir

Introduction

Go Language, un langage spécialement conçu pour la concurrency, chaque fois que vous démarrez un microthread, cela coûte environ pour en créer un 2KB2KB起步

假设一个内存条大小4G,一个微线程2kb1G=1024M=1048576kb1048576/2=524288,五十多万个

但是你知道像Java,Python等语言,一个线程代价多大吗???,2MB起步,代价直接翻了千倍

所以,激动吧,随便用Go写一个web程序,基本都相当于NginxMise en route

🎜

🎜Supposez une taille de clé USB🎜🎜🎜4G🎜🎜🎜, un micro-thread🎜🎜 🎜2ko🎜🎜🎜, 🎜🎜 1G=1024M=1048576ko 🎜🎜, 🎜🎜🎜Mais savez-vous combien coûte un fil de discussion dans des langages comme Java, Python et d'autres langages ???,🎜🎜2MB🎜🎜Au départ, le prix a directement doublé mille fois🎜🎜

🎜Alors, excité, écrivez simplement un programme web en Go, c'est fondamentalement équivalent à 🎜🎜 Nginx🎜🎜

<code style="font-family: var(--monospace);vertical-align: initial;border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;"><br>

goroutine

Go中的微线程,也叫做goroutinegoroutine是并行处理任务的

就像我用两只手同时操作两个手机打游戏一样

而不是一个手玩玩这个,一个手玩玩那个,这样切换式玩法

goroutine由Go的runtime完成调度,goroutinegoroutine

Go中的微线程,也叫做

goroutine

goroutine🎜🎜是并行处理任务的🎜🎜

style="hauteur de ligne : hériter ; orphelins : 4 ; marge supérieure : 0,8 em ; marge inférieure : 0,8 em ; espace blanc : pré-enveloppement ; famille de polices : "Open Sans", "Clear Sans", " Helvetica Neue", Helvetica, Arial, sans-serif;font-size: 16px;text-align: start;">

🎜goroutine🎜🎜由Go的🎜🎜runtime🎜🎜完成调度,🎜🎜goroutine🎜🎜的本质是在代码(用户态)级别完成的切换,代价很小🎜🎜🎜 🎜像Java, Python

En raison de goroutinegoroutine是由runtime完成切换,并且runtime经过Google公司的数位大佬优化,已经很小母牛上山了,牛逼哄哄了。


使用goroutine

在Go中使用goroutine很简单,只需要在想调用的函数前加一个go就行了,这就代表启动了一个goroutine Oui Par

🎜🎜🎜

🎜Utiliser goroutine🎜

🎜Utiliser dans Go🎜🎜goroutine🎜🎜 est très simple, vous n'avez qu'à l'appeler quand vous le souhaitez 🎜 Ajoutez simplement go avant la fonction🎜🎜, ce qui signifie qu'un 🎜🎜goroutine🎜🎜

Méthode de fonction d'appel normal

Fonction

func Say() {
    time.Sleep(time.Second)
    fmt.Println("我在说话说了1s说完了...")
}

main

func main() {
    //开始时间
    var start_time = time.Now()
    //启动10个say说话
    for i := 0; i < 10; i++ {
        Say()
}
    //结束时间
    var end_time = time.Now()
    //计算时间差
    fmt.Println(end_time.Sub(start_time))
}

Résultat de l'exécution

Un article pour vous présenter les bases de la simultanéité du langage Go

Ça a bouclé 10 fois et a pris 10 secondes, ce qui est un peu lent!


méthode goroutine d'appel de fonctions

La fonction est toujours la fonction ci-dessus

main

func main() {
    //开始时间
    var start_time = time.Now()
    //启动10个say说话
    for i := 0; i < 10; i++ {
        go Say()
}
    //结束时间
    var end_time = time.Now()
    //计算时间差
    fmt.Println(end_time.Sub(start_time))
}

Remarque : Ligne 6, ajoutez entrez mot-clé front, le mot-clé go signifie exécuter cette fonction séparément dans un micro-thread.

Résultats d'exécution

Un article pour vous présenter les bases de la simultanéité du langage Go

quoi ??? 0, que se passe-t-il ?


Pourquoi cette situation de 0 se produit-elle

C'est parce que, dans Go, nous utilisons la méthode du thread démon. Qu'est-ce que cela signifie ?

Un article pour vous présenter les bases de la simultanéité du langage Go

En Go, tant que la fonction principale est exécutée, les autres micro-threads seront inactifs.

Tout comme certains monstres, ils dépendent les uns des autres et ont un corps maternel. Si le corps maternel meurt, le bébé en dessous mourra également.

Alors, comment résoudre ce problème ???


sync.WaitGroup

Comme mentionné ci-dessus, nous avons constaté que certains micro-threads avaient démarré, mais les micro-threads étaient morts avant ils ont pu être exécutés. , parce que la fonction main s'est exécutée trop vite, main a fini de s'exécuter et le runtime Go a automatiquement fermé les autres micro-threads.

Alors réfléchissez-y, comment pouvons-nous faire main à la finAttendez une minute, quand mes enfants seront de retour, je continuerai à courir.

所以,有一个新的问题,那就是等,祭出法宝sync.WaitGroup

先看一下怎么用

函数

func Say() {
    //函数结束时取消标记
    defer wg.Done()
    //每个函数在启动时加上一个标记
    wg.Add(1)
    //函数开始打上一个标记
    time.Sleep(time.Second*1)
    fmt.Println("我在说话说了1s说完了...")
}

main

var wg  sync.WaitGroup
func main() {
    //开始时间
    var start_time = time.Now()
    //启动10个say说话
    for i := 0; i < 10; i++ {
        go Say()
}
    // 等待所有标记过的微线程执行完毕
    wg.Wait()
    //结束时间
    var end_time = time.Now()
    //计算时间差
    fmt.Println(end_time.Sub(start_time))
}

执行结果

Un article pour vous présenter les bases de la simultanéité du langage Go

可以看到,10个线程同时启动,1s就完了,并且代码相对简单,就算开启10w个,还是1s多一点

这也是为什么很多公司越来越青睐Go的原因。

Un article pour vous présenter les bases de la simultanéité du langage Go

runtime.GOMAXPROCS

这个意思要使用多少个核,默认使用全部核心,性能跑满,但是也有意外的情况,

比如一个机器跑了很多其他任务,Go写的这个是不太重要的任务,但是是计算型的,这时候理论来说是不尽量挤兑别人的算力

所以要限制一下当前程序使用电脑的算力

代码

func main() {
    //本机的cpu个数
    var cpuNum = runtime.NumCPU()
    fmt.Println(cpuNum)
    //设置Go使用cpu个数
    runtime.GOMAXPROCS(4)
}


总结

上述我们学习了Go的并发,学习了

  • 如何创建一个协程(goroutine)。

  • 为什么需要sync.WaitGroup

  • 设置当前程序使用CPU核数。

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:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer