In the previous article, we discussed concurrency, and the differences between concurrency and parallelism. In this tutorial we will discuss how to implement concurrency through the go process in go.
What is a co-process
The Go Association (goroutine) is a function or method that runs concurrently with other functions or methods. You can think of the go process as a lightweight thread. The cost of creating a go process is small compared to creating a thread. So it's very common to run thousands of concurrent processes in go.
Advantages of the Go process vs. threading
- The go process has very little overhead compared to threads. The stack size of the go process is only a few kilobytes, which can grow and shrink depending on the needs of the application, and the thread must specify the size of the stack, and the stack size is fixed.
- The go path is multiplexed to fewer OS threads. In one program, thousands of go processes may only be running in one thread. If any of the go threads in the thread are blocked (such as waiting for user input), go creates a new OS thread and moves the rest of the go to the new OS thread. All of this is done by runtime, and our programmers don't have to worry about these complicated details, just take advantage of the simple API that Go provides to handle concurrency.
- The Go process communicates through channels. The channel prevents the risk of race condition when multiple threads are accessing shared memory. A channel can be imagined as a conduit for communication between multiple processes. We'll cover the channel in the next tutorial.
How do I create a co-process?
Add a keyword before a function or method call go
, so that a concurrent go association is turned on.
Let's create a co-process:
Package Mainimport ( "fmt") func hello () { fmt. Println ("Hello World goroutine")}func main () { go Hello () FMT. Println ("main function")}
The 11th line go hello()
opens up a new co-process. Now hello()
the function will main()
run with the function. The main
function runs in a separate co-process, which is called the main coprocessor.
Run this program and you will get a surprise.
The program only outputs one line of text: main function
. What happened to the co-process we created? We need to understand the two properties of the go process to see why this happens.
- When you create a go process, the statement that creates the go process returns immediately. Unlike functions, the program flow does not wait for the go process to end before continuing. The program flow returns and executes the next line of code immediately after the go process is turned on, ignoring any return values from the go process.
- Other co-processes can be run when the main process is present, the program terminates when the main process terminates, and the other threads are terminated.
I think you already know why our process is not running. After 11 lines are called go hello()
, the program's flow is reversed directly to the next statement execution, and does not wait for hello
the coprocessor to exit and then print main function
. Then the main process ends and no more code is executed, so hello
the process does not get the chance to run.
Let's fix this problem:
package mainimport ( " fmt " " time " ) func Hello () {fmt. Println ( " hello World goroutine Span style= "COLOR: #800000" > " )}func Main () {go hello () time. Sleep ( 1 * time. Second) fmt. Println ( " main function " )}
In the above program, line 13th, we call the time packet's sleep function to make the call to the function of the same thread hibernate. This is where the main process sleeps for 1 seconds. The call now go hello()
has enough time to execute before the main process exits. The program prints first Hello world goroutine
, waits 1 seconds after printing main function
.
The method of using the Sleep function to wait for other threads to end in the main process is not normal, and we use it here just to illustrate how the go process works. The channel can be used to block the main coprocessor until other processes have finished executing. We'll discuss the channel in the next tutorial.
Turn on multiple co-processes
Let's write a program that opens multiple threads to better understand the association:
Package Mainimport ("FMT" " Time") func numbers () { forI: =1; I <=5; i++{time. Sleep ( -*Time.millisecond) fmt. Printf ("%d", I)}} Func alphabets () { forI: ='a'; I <='e'; i++{time. Sleep ( -*Time.millisecond) fmt. Printf ("%c", I)}} Func main () {go numbers () go alphabets () time. Sleep ( the*Time.millisecond) fmt. Println ("Main terminated")}
The above program opens two threads in lines 21st and 22. The two processes are now executing simultaneously. The numbers
co-process initially sleeps 250 milliseconds, then prints 1, then sleeps again and then prints 2, and so on, until it prints to 5. Similarly, the alphabets
co-process prints letters from A to E, with each letter 400 milliseconds apart. The main coprocessor numbers
is opened and alphabets
co-processes, waiting 3000 milliseconds, and finally terminating.
The output of the program is:
1 2 3 4 5 d E Main terminated
The following picture describes how this program works
, the blue wireframe indicates the numbers
co-process, and the Maroon wireframe indicates the alphabets
process. The green wireframe indicates the main process. The black wireframe incorporates the three processes above, showing us how the program works. The string representing the 0ms,250 ms at the top of each box represents the time in milliseconds, at the bottom of each box, that represents the output.
The blue wireframe tells us that 250ms
when we print 1, we 500ms
print 2, and so on. So the output from the bottom of the last wireframe 1 a 2 3 b 4 c 5 d e main terminated
is the output of the entire program. The image above is well understood and you will be able to understand how the program works.
This article transferred from: Https://blog.csdn.net/u011304970/article/details/75096323?locationNum=3&fps=1