An article to introduce you to the basics of Go language concurrency

Release: 2023-07-21 10:33:26
forward
896 people have browsed it

Introduction

Go language, specifically for Concurrency# A language born with ##, each time you start a micro-thread the cost of creating one is about 2KB Getting Started

Assume a memory stick size of 4G, a micro-thread 2kb1G=1024M=1048576kb 1048576/2=524288, more than half a million

But do you know how much a thread costs in languages ​​such as Java and Python? ???, 2MB starts with the price directly doubled a thousand times

So, get excited and use it as you like Writing a web program in Go is basically equivalent to Nginx

<br>

goroutine

Micro-threads in Go are also called goroutine, goroutine is the

## for parallel processing tasks

#Just like I use two hands to operate two mobile phones at the same time to play games

Instead of playing this with one hand and playing that with one hand, this is a switching method

goroutineScheduling is completed by Go’s runtime,# The essence of ##goroutine is to switch at the code (user mode) level, the cost is very small

Like Java, Threads in languages ​​such as Python are implemented at the operating system (kernel state) level, so the cost is very high

Since goroutine is switched by runtime, AndruntimeAfter optimization by Google’s digital bosses, it’s already a very small cow going up the mountain, and it’s awesome.

<br>

Using goroutine

Using in Gogoroutine is very simple. You just need to add a go before the function you want to call. This is It means starting a goroutine<h3 cid="n21" mdtype="heading" style='break-after: avoid-page;break-inside: avoid;font-size: 1.5em;margin-top: 1rem;margin-bottom: 1rem;font-weight: bold;line-height: 1.43;cursor: text;white-space: pre-wrap;font-family: "Open Sans", "Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;text-align: start;'><span md-inline="plain">Normal calling function method</span></h3> <h4 cid="n22" mdtype="heading" style='break-after: avoid-page;break-inside: avoid;font-size: 1.25em;margin-top: 1rem;margin-bottom: 1rem;font-weight: bold;line-height: 1.4;cursor: text;white-space: pre-wrap;font-family: "Open Sans", "Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;text-align: start;'><span md-inline="plain">Function</span></h4> <section class="code-snippet__fix code-snippet__js"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">func Say() { time.Sleep(time.Second) fmt.Println(&quot;我在说话说了1s说完了...&quot;) }</pre><div class="contentsignin">Copy after login</div></div></section><h4 cid="n24" mdtype="heading" style="break-after: avoid-page;break-inside: avoid;font-size: 1.25em;margin-top: 1rem;margin-bottom: 1rem;font-weight: bold;line-height: 1.4;cursor: text;white-space: pre-wrap;font-family: "Open Sans", "Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;text-align: start;"><span md-inline="plain">main</span><br/></h4><section class="code-snippet__fix code-snippet__js"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">func main() { //开始时间 var start_time = time.Now() //启动10个say说话 for i := 0; i &lt; 10; i++ { Say() } //结束时间 var end_time = time.Now() //计算时间差 fmt.Println(end_time.Sub(start_time)) }</pre><div class="contentsignin">Copy after login</div></div></section><h4 cid="n26" mdtype="heading" style="break-after: avoid-page;break-inside: avoid;font-size: 1.25em;margin-top: 1rem;margin-bottom: 1rem;font-weight: bold;line-height: 1.4;cursor: text;white-space: pre-wrap;font-family: "Open Sans", "Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;text-align: start;"><span md-inline="plain">Execution result</span><br/></h4><p style="text-align: center;margin-bottom: 0px;"><img src="https://img.php.cn/upload/article/001/272/559/78b9efff24395df3a9c684c869f26364-0.png"/ alt="An article to introduce you to the basics of Go language concurrency" ></p><p cid="n28" mdtype="paragraph" style="max-width:90%">##It looped 10 times and took 10s. A bit slow! <span md-inline="plain"></span><br/></p><p cid="n28" mdtype="paragraph" style="line-height: inherit;orphans: 4;margin-top: 0.8em;margin-bottom: 0.8em;white-space: pre-wrap;font-family: "Open Sans", "Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;font-size: 16px;text-align: start;"><span md-inline="plain"><br/></span></p><h3 cid="n29" mdtype="heading" style="break-after: avoid-page;break-inside: avoid;font-size: 1.5em;margin-top: 1rem;margin-bottom: 1rem;font-weight: bold;line-height: 1.43;cursor: text;white-space: pre-wrap;font-family: "Open Sans", "Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;text-align: start;">goroutine calling function method<span md-inline="plain"></span></h3><p cid="n30" mdtype="paragraph" style="line-height: inherit;orphans: 4;margin-top: 0.8em;margin-bottom: 0.8em;white-space: pre-wrap;font-family: "Open Sans", "Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;font-size: 16px;text-align: start;">The function is still the same as above Function <span md-inline="plain"></span></p><h4 cid="n31" mdtype="heading" style="break-after: avoid-page;break-inside: avoid;font-size: 1.25em;margin-top: 1rem;margin-bottom: 1rem;font-weight: bold;line-height: 1.4;cursor: text;white-space: pre-wrap;font-family: "Open Sans", "Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;text-align: start;">main<span md-inline="plain"></span></h4><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">func main() { //开始时间 var start_time = time.Now() //启动10个say说话 for i := 0; i &lt; 10; i++ { go Say() } //结束时间 var end_time = time.Now() //计算时间差 fmt.Println(end_time.Sub(start_time)) }</pre><div class="contentsignin">Copy after login</div></div><section class="code-snippet__fix code-snippet__js"></section><p cid="n33" mdtype="paragraph" style="line-height: inherit;orphans: 4;margin-top: 0.8em;margin-bottom: 0.8em;white-space: pre-wrap;font-family: "Open Sans", "Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;font-size: 16px;text-align: start;"><span md-inline="strong">Note: <strong></strong></span> Line 6 , with the go keyword added in front, the go keyword means running this function separately in a micro-thread. <span md-inline="plain"></span><br/></p><h4 cid="n34" mdtype="heading" style="break-after: avoid-page;break-inside: avoid;font-size: 1.25em;margin-top: 1rem;margin-bottom: 1rem;font-weight: bold;line-height: 1.4;cursor: text;white-space: pre-wrap;font-family: "Open Sans", "Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;text-align: start;">Results of the<span md-inline="plain"></span></h4><p style="text-align: center;margin-bottom: 0px;"><img src="https://img.php.cn/upload/article/001/272/559/1643117875c6272543e2207ef88f6b3c-1.png"/ alt="An article to introduce you to the basics of Go language concurrency" ><p cid="n36" mdtype="paragraph" style="max-width:90%"><span md-inline="plain">what??? 0s, what’s going on? </span><br/></p><p cid="n36" mdtype="paragraph" style="line-height: inherit;orphans: 4;margin-top: 0.8em;margin-bottom: 0.8em;white-space: pre-wrap;font-family: "Open Sans", "Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;font-size: 16px;text-align: start;"><span md-inline="plain"><br/></span></p><h2 cid="n37" mdtype="heading" style="break-after: avoid-page;break-inside: avoid;font-size: 1.75em;margin-top: 1rem;margin-bottom: 1rem;font-weight: bold;line-height: 1.225;cursor: text;padding-bottom: 0.3em;border-bottom: 1px solid rgb(238, 238, 238);white-space: pre-wrap;font-family: "Open Sans", "Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;text-align: start;"><span md-inline="plain">Why does this situation of 0s occur</span></h2><p cid="n38" mdtype="paragraph" style="line-height: inherit;orphans: 4;margin-top: 0.8em;margin-bottom: 0.8em;white-space: pre-wrap;font-family: "Open Sans", "Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;font-size: 16px;text-align: start;"><span md-inline="plain">This It's because, in Go, we use the daemon thread method. What does that mean? </span></p><p style="text-align: center;margin-bottom: 0px;"><img src="https://img.php.cn/upload/article/001/272/559/1643117875c6272543e2207ef88f6b3c-2.png"/ alt="An article to introduce you to the basics of Go language concurrency" ></p><p cid="n40" mdtype="paragraph" style="max-width:90%"><span md-inline="plain">In Go, as long as the main function is executed, other micro-threads will be idle. </span></p><p cid="n41" mdtype="paragraph" style="line-height: inherit;orphans: 4;margin-top: 0.8em;margin-bottom: 0.8em;white-space: pre-wrap;font-family: "Open Sans", "Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;font-size: 16px;text-align: start;"><span md-inline="plain">Just like some monsters, they depend on each other and have a mother. If the mother dies, the baby below will also die. </span></p><p cid="n42" mdtype="paragraph" style="line-height: inherit;orphans: 4;margin-top: 0.8em;margin-bottom: 0.8em;white-space: pre-wrap;font-family: "Open Sans", "Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;font-size: 16px;text-align: start;"><span md-inline="plain">So how to solve this problem???</span></p><p cid="n42" mdtype="paragraph" style="line-height: inherit;orphans: 4;margin-top: 0.8em;margin-bottom: 0.8em;white-space: pre-wrap;font-family: "Open Sans", "Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;font-size: 16px;text-align: start;"><span md-inline="plain"><br/></span></p><h2 cid="n43" mdtype="heading" style="break-after: avoid-page;break-inside: avoid;font-size: 1.75em;margin-top: 1rem;margin-bottom: 1rem;font-weight: bold;line-height: 1.225;cursor: text;padding-bottom: 0.3em;border-bottom: 1px solid rgb(238, 238, 238);white-space: pre-wrap;font-family: "Open Sans", "Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;text-align: start;"><span md-inline="plain">sync .WaitGroup</span></h2><p cid="n44" mdtype="paragraph" style="line-height: inherit;orphans: 4;margin-top: 0.8em;margin-bottom: 0.8em;white-space: pre-wrap;font-family: "Open Sans", "Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;font-size: 16px;text-align: start;"><span md-inline="plain">We found above that some micro-threads were started, but the micro-threads hung up before they had time to execute. This is because </span><span md-inline="strong"><strong>main function</strong></span><span md-inline="plain">It ran too fast, </span><span md-inline="strong"><strong>main finished running</strong></span><span md-inline="plain">, and other micro-threads were automatically closed when Go was running. </span></p><p cid="n45" mdtype="paragraph" style="line-height: inherit;orphans: 4;margin-top: 0.8em;margin-bottom: 0.8em;white-space: pre-wrap;font-family: "Open Sans", "Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;font-size: 16px;text-align: start;"><span md-inline="plain">Then think about it on the other hand, how can we make </span><span md-inline="strong"><strong>main at the end</strong></span><span md-inline="plain">Wait a moment, wait until my children are all I’m back and I’m continuing to run. </span></p><p cid="n46" mdtype="paragraph" style="line-height: inherit;orphans: 4;margin-top: 0.8em;margin-bottom: 0.8em;white-space: pre-wrap;font-family: "Open Sans", "Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;font-size: 16px;text-align: start;"><span md-inline="plain">所以,有一个新的问题,那就是等,祭出法宝</span><span md-inline="code" spellcheck="false"><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;">sync.WaitGroup

先看一下怎么用

函数

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

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))
}
Copy after login

执行结果

An article to introduce you to the basics of Go language concurrency

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

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

An article to introduce you to the basics of Go language concurrency

runtime.GOMAXPROCS

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

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

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

代码

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

<br>

总结<br>

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

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

  • 为什么需要sync.WaitGroup

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

The above is the detailed content of An article to introduce you to the basics of Go language concurrency. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:Go语言进阶学习
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template