This is a creation in Article, where the information may have evolved or changed.
Statement
Reprint please specify the address of this article, thank:)
Understanding processes, threads, and co-routines
This article does not explain in detail the meaning of these three nouns, there is an article below, do not understand the classmate can refer to see.
- Http://www.cnblogs.com/work115/p/5620272.html
Use of Goroutine
- Goroutine pursues communication to share memory instead of shared memory to communicate
- Using Goroutine is very simple, just need to use a keyword go, we use a piece of code to sample how to use the Go keyword
12345678910111213 |
Package mainimport ("FMT")funcmain() {go Goroutine ()}funcgoroutine() {fmt. Println ("Goroutine")} |
No output?
- After executing the above code, you will find that nothing is output, so what is the problem?
Because our current program, is only a single-threaded program, the main function as long as the execution is finished, it will not be the other threads do what things, the program automatically exits. Then we think of a way to add a sleep function, so that the main function waits for the Goroutine function to complete before exiting.
The changed code is as follows:
123456789101112131415 |
Package mainimport ("FMT""Time")funcmain() {go goroutine () time. Sleep (3 * time. Second)}funcgoroutine() {fmt. Println ("Goroutine")} |
- As expected, the program successfully printed out the "Goroutine" string.
Introduction of Channel
- Through the above experiment, we succeeded in using the Goroutine and printed out a word. Now that's the problem, it's not what we want. Why? What if the code in my Goroutine function needs to execute 10s, 20s, or more? Is it still more seconds to sleep?
- What we need is that when the Goroutine function is finished, the main function is automatically notified. So here we get the channel.
How to create
Channel use make to create
Incoming data to the channel
Output the data in the channel
Then we improve the code that uses the Sleep method above, and replace it with the channel version
- The code is as follows:
12345678910111213141516 |
package mainimport () func main Span class= "params" > () {Chann: = make (chan bool ) go func () {fmt. Println ( "Goroutine" ) Chann <-true } () <-Chann} |
- If you successfully output the Goroutine after running the code snippet above, then it is true that we are writing. Now let's understand the meaning of this code, we look outside the anonymous function,
<-chann
this is actually a blocking effect, when the anonymous function inside the business is not finished and speak true in the channel, the program will not exit, anonymous function outside will be waiting. When the anonymous function is executed, that is, chann <- true
when True is passed to the channel, it will not continue to block, and the program will end. This is the role of the channel.
Iterate output channel with for range
- It is important to note that when you iterate over the channel, you must close the channel explicitly in a certain location, or the program will deadlock. Let's use a snippet to sample:
1234567891011121314151617181920 |
package mainimport ( "FMT" ) func main () {Chann: = make ( Chan bool ) go func {fmt. Println ( "Goroutine" ) Chann <-true close (Chann) //close channel } () for V: = range Chann {fmt. Println (v)}} |
Definition type of Channel
- Definition format for Channel type:
ChannelType = ("chan" | "chan" "<-" | "<-" "chan")
- The channel contains three types of definitions, and the optional <-represents the direction of the channel. If you do not specify a direction, the channel is bidirectional, and you can either accept the data or send the data.
chan T
Can be received or sent
chan <- bool
Can send data of type bool
<- chan bool
Can receive data of type int
Non-buffered channel and buffer channel
Non-buffered channel
- How to define
chann := make(chan int)
- The so-called unbuffered channel can only pass in 1 values in the channel, if the incoming value has not been taken away, it will be blocked until it is taken away. Can be said to be synchronous blocking
- It should be noted that the non-buffered channel must be first taken and then transmitted. When a fetch occurs in the code, it is found that there is no value in the channel, then a blockage occurs, and when the channel has a value, it stops blocking.
Buffer Channel
- How to define
chann := make(chan int,100)
- There is a buffer channel, such as the buffer value is 100, then unless the incoming value has reached 100, otherwise the channel, or can continue to pass the value in. When the channel is full, a blockage occurs, and the value is taken away before it can continue to be transmitted.
How to tell if a group of tasks is complete
Using buffer Channel
12345678910111213141516171819202122232425262728 |
PackageMainImport("FMT""Runtime") func main() {Runtime. Gomaxprocs (runtime. NUMCPU ())//Set the number of threads to the current computer's number of CPUsChann: = Make(Chan BOOL,Ten) forI: =0; I <Ten; i++ {GoGo (Chann, I)} forI: =0; I <Ten; i++ {<-chann}} func Go(Chann chan bool, index int) {A: =1 forI: =0; I <100000000; i++ {A + =1}fmt. PRINTLN (Index, a) Chann <-true} |
Using the Sync Pack
- By setting a task group, the size is 10. Once each task is completed, the
wg.Done()
program automatically exits when 10 tasks are completed.
1234567891011121314151617181920212223242526272829 |
package mainimport ( "sync" ) func main () {runtime. Gomaxprocs (runtime. NUMCPU ()) WG: =sync. WAITGROUP{}WG. ADD (10 ) for i: = 0 ; I < 10 ; i++ {go go (&WG, i)}wg. Wait ()}func go int ) {A: = 1 for i: = 0 ; I < 100000000 ; i++ {A + = 1 }fmt. PRINTLN (Index, a) WG. Done ()}
|
Select
Select is used to listen for multiple channel and send and receive messages, when any one case satisfies the conditions will be executed, if there is no executable, will execute the default, if there is no default, the program will block.
12345678910111213141516171819202122232425262728293031 |
PackageMainImport("FMT""Time") func main() {Chann: = Make(Chan int)GoEnqueue (Chann) for{Select{ CaseV, OK: = <-chann:ifOK {fmt. Println (v)}Else{FMT. Println ("Close")return}default: FMT. Println ("Waiting")}}} func enqueue(Chann chan int) {time. Sleep (3* Time. Second) Chann <-1Close(Chann)} |
Reference
- http://blog.csdn.net/gaox587/article/details/53005575
- http://blog.csdn.net/shachao888/article/details/52944212
- Https://github.com/Unknwon/go-fundamental-programming/blob/master/lectures/lecture14.md