With the "Subversion storm" caused by the blockchain, a large number of blockchain training institutions emerged. But in a mixed-up training circle, it is bucket to find a truly standard course system and a dedicated professional lecturer in the Blockchain field. Brother even education pointed out that it is time to make action to change and subvert the traditional training institutions operating thinking, and remind the public users, should be rational choice of blockchain training institutions.
As a modern language, the go language implements native support for concurrency.
Behavior of the SELECT statement
For the sake of understanding, we first give a snippet of code:
Https://talks.golang.org/2012/concurrency.slide#32
Select {
Case v1: = <-c1:
Fmt. Printf ("Received%v from c1\n", v1)
Case V2: = <-c2:
Fmt. Printf ("Received%v from c2\n", v1)
Case C3 <-23:
Fmt. Printf ("Sent%v to c3\n", 23)
Default
Fmt. Printf ("No one is ready to communicate\n")
}
In the above code, the SELECT statement has four case statements, the first two are receive operations, the third is the send operation, and the last is the default action. When the code executes to select, the case statement is evaluated in the order of the source code and evaluated only once, and the results of the evaluation can occur in the following cases:
In addition to the default, if only one case statement is passed, execute the statement in it;
In addition to the default, if there are multiple case statements evaluated through, then randomly selected by pseudo-random method;
If the case statement outside of default does not pass the evaluation, then execute the statement in default;
If there is no default, then blocks of code will be blocked, directing a case to pass the evaluation;
If the object of the receive operation in the case statement is the nil channel, it will also block, so let's look at a more comprehensive, more advanced example:
Https://golang.org/ref/spec#Select_statements
var a []int
var c, C1, C2, C3, C4 Chan int
var i1, I2 int
Select {
Case I1 = <-c1:
Print ("Received", I1, "from c1\n")
Case C2 <-i2:
Print ("Sent", I2, "to c2\n")
Case i3, OK: = (<-C3)://Same as:i3, OK: = <-c3
If OK {
Print ("Received", i3, "from c3\n")
} else {
Print ("C3 is Closed\n")
}
Case A[f ()] = <-c4:
Same as:
Case T: = <-c4
A[f ()] = t
Default
Print ("No communication\n")
}
For {//send random bit string to channel C
Select {
Case C <-0://note:no statement, no Fallthrough, no folding of cases
Case C <-1:
}
}
Select {}//block permanently
Note: Unlike traditional programming languages such as C + +, the Go Language case statement does not require the break keyword to jump out of select.
Use of Select
Set the time-out for a request
Before Golang 1.7, HTTP packets were not introduced to the context support via HTTP. A Client sending a request to a broken service can cause a slow response. In a similar scenario, we can use Select to control the response time of the service, and here is a simple demo:
Func Main () {
c: = Boring ("Joe")
Timeout: = time. After (5 * time. Second)
for {
Select {
Case S: = <-c:
Fmt. PRINTLN (s)
Case <-timeout:
Fmt. Println ("You talk Too much.")
Return
}
}
}
Done Channel
Https://github.com/golang/net/blob/release-branch.go1.7/context/ctxhttp/ctxhttp.go
Do sends a HTTP request with the provided HTTP. Client and returns
An HTTP response.
//
If the client is nil, http. Defaultclient is used.
//
The provided CTX must be non-nil. If It is a canceled or times out,
CTx. ERR () would be returned.
Func Do (CTX context. Context, client *http. Client, req *http. Request) (*http. Response, error) {
If client = = Nil {
Client = http. Defaultclient
}
RESP, err: = client. Do (req. Withcontext (CTX))
If we got an error, and the context has been canceled,
The context ' s error is probably more useful.
If err! = Nil {
Select {
Case <-ctx. Done ():
Err = ctx. ERR ()
Default
}
}
Return RESP, err
}
Quit Channel
In many scenarios, the Quit channel and the done channel are a concept. In concurrent programs, it is common for main routine to assign tasks to other go routine, which is just a function of scheduling. In this case, the main function does not know whether the other Goroutine tasks are complete, we need the Quit channel at this point, and for finer-grained controls, such as how much to complete, or the done channel. Here is an example of the Quit channel, first of which is main routine:
Create a quit channel
Quit: = Make (Chan string)
Start producer Goroutine
c: = Boring ("Joe", quit)
Read results from producer Channel
For I: = Rand. INTN (10); I >= 0; i--{fmt. Println (<-C)}
Notify producers to stop production through the Quit channel
Quit <-"bye!"
Fmt. Printf ("Joe says:%q\n", <-quit)
Let's look at the parts related to the Quit channel in producer go routine:
Select {
Case C <-FMT. Sprintf ("%s:%d", MSG, i):
Do nothing
Case <-quit:
Cleanup ()
Quit <-"See you!"
Return
}