Routine-Channel, the core of Go language

Routine-Channel, the core of Go language

peiyu1988
Blog Garden     Homepage     New Essay     Contact     Subscribe     Management Essays-23 Articles-0 Comments-23 trackbacks-0
< April 2018 >
day One two three four Fives six
25 26 27 28 29 30 31
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 1 2 3 4 5

Nickname: peiyu1988
Age: 1 year
Followers: 20
Follow: 1 +Follow

search for

   

Most used link

My tag

Essay file

latest comment

Read the leaderboard

Comment leaderboard

Recommended ranking

Routine-Channel, the core of Go language

Preface

The Go language provides support for concurrent programming through routines.

Routine features

(1) Goroutine is a function of the Go language runtime, not a function provided by the operating system. Goroutine is not implemented by threads.

Example: start a routine

Go + function name can start a goroutine

?
1 2 3 4 5 6 7 8 9 10 package main import (     "fmt" ) func p() {     fmt.PrintLn("hello py") } func main() {      go p() }

(2) A goroutine is a piece of code, a function entry, and a stack allocated for it on the heap. So it is very cheap, we can easily create tens of thousands of goroutines, but they are not scheduled for execution by the operating system.
(3) Except for threads blocked by system calls, the Go runtime library will start up to $GOMAXPROCS threads to run goroutines.

Example: Use GOMAXPROCS (set the number of CPUs)

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 package main   import     "runtime"     "time" )   var _ = runtime.GOMAXPROCS(3)   var a, b int   func u1() {      a = 1     b = 2 }   func u2() {      a = 3     b = 4 }   func p() {      println(a)     println(b) }   func main() {      go u1()     go u2()     go p()     time.Sleep(1 * time.Second) }

(4) The goroutine is cooperatively scheduled. If the goroutine will execute for a long time and is not synchronized by waiting to read or write the channel data, you need to actively call Gosched() to free the CPU.

Example: Gosched() gives up the CPU

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package main   import (     "fmt"     "runtime" )   func say(s string) {     for i := 0; i < 2; i++ {         runtime.Gosched()         fmt.Println(s)     } }   func main() {     go say("world")     say("hello") }

(5) Like all coroutines in other concurrent frameworks, the so-called "lock-free" advantage in goroutine is only valid in a single thread. If $GOMAXPROCS> 1 and communication between coroutines is required, the Go runtime library will be responsible for locking protection Data, this is also the reason why an example like sieve.go is slower with multiple CPUs and multiple threads.
(6) The requests to be processed by server-side programs such as Web are essentially parallel processing. Each request is basically independent, independent of each other, and almost no data interaction. This is not a concurrent programming model, but a concurrent programming framework is just Solving the complexity of its semantic expression is not to fundamentally improve the efficiency of processing. Maybe the English of concurrent connection and concurrent programming is concurrent. It is easy to produce "concurrent programming framework and coroutine can efficiently handle a large number of concurrent connections" misunderstanding.
(7) The Go language runtime encapsulates asynchronous IO, so it is possible to write servers that seem to have a lot of concurrent, but even if we adjust $GOMAXPROCS to make full use of multi-core CPU parallel processing, its efficiency is not as good as our use of IO event-driven design , Divide the appropriate proportion of the thread pool according to the transaction type. In terms of response time, collaborative scheduling is a flaw.
(8) The biggest value of goroutine is that it realizes the mapping and dynamic expansion of concurrent coroutines and actual parallel execution threads. With the continuous development and improvement of its runtime library, its performance will definitely get better and better, especially in CPU In the future with more and more cores, one day we will abandon the little performance difference for the sake of simplicity and maintainability of the code.

Routine communication: Channel

Communication between routines is through Channel; Channel is intra-process communication and does not support out-of-process communication.

syntax

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 // ElemType var chanName chan ElemType // int var ch chan int // map bool channel var m map[string] chan bool // , make() + ch := make(chan int) // size, size 100 ch := make(chan int, 100)    // <- chan // , // goroutine ch<- value // value := <-ch    // var ch1 chan<- float64     // float64 var ch2 <-chan int         // int   // channel close() close(ch) // ch ok false, ( ) x, ok := <-ch

 What kind of scenarios use pipelines?

First of all, we know that Channel can communicate in routines, as in the following example:

?
package main import "fmt"    func print() {      fmt.Println("Hello world") }     func main() {    for i := 0; i < 10; i++ {         go print()    }  }

 The above code roughly means: use the coroutine to output "Hello world" 10 times in parallel, but when you run the above code, you will find that there will be no output. This is because although the go keyword is used to create the coroutine, the main function has exited and the process has been closed before it is executed, so the coroutine that has been started will not be executed.

If you have C-related multi-threading experience, you can change the coroutine to a thread, and then call the join method of the thread to let the main thread wait for the child thread to finish executing before exiting. In the Go language, we can use the write blocking and read blocking of the pipeline to complete the behavior similar to thread join. The code is as follows:

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package main import "fmt"    func print(ch chan int) {     fmt.Println("Hello world")     ch<- 1 }    func main() {     chs := make([]chan int)     for i := 0; i < 10; i++ {        chs[i] = make(chan int)        go print(chs[i])     }           for _, ch := range(chs){         <-ch     } }

 Through the above code, we can complete the effect of outputting 10 lines of Hello world in parallel.

 

posted on 2018-04-10 19:37 peiyu1988 Reading (92) Comments (1) Edit collection
FeedBack: #1 Floor 19:40:48 2018-04-10 19:40 39479962018/4/10  mrcorrection   FavoritedFavorite Support (0) against (0)   Refresh comments refresh the page Top to post a comment registered user login, please login or register , visit the website home page. [Recommended] Over 500,000 VC++ source code: Large-scale configuration industrial control, power simulation CAD and GIS source code library!
[Registration] 2050 Conference-Blog Garden Programmers Reunion (5.25 Hangzhou Yunqi Town)
[Recruitment] We are serious about finding technical experts at a high price!
[Tencent Cloud] Buy domain name, get analysis + SSL certificate + build website
The latest IT news :
"Alipay" entered the HSK test questions of the Chinese Proficiency Test, foreigners went crazy on the spot
MediaTek's first quarter revenue of US$1.7 billion fell year-on-year but in line with expectations
Spotify plans to launch a new version of free music services to attract more new users
Zuckerberg explained why the founder
of Oculus VR was fired . WeChat and QQ will suspend the direct playback function of short video apps outside the chain
more news... Latest Knowledge Base articles :
written autodidact Getting Started
and programmers love
Learning to learn
Excellent people management technology trap
As a programmer, you in the end how important math
>> More Knowledge Base article .. . today in history:
2017-04-10 Nodejs true multithreading.
2017-04-10 Nodejs use Redis
Copyright 2018 peiyu1988 Powered by: blog garden templates provide: HJ blog