A, goroutine basis
definition
- Users assigned enough task, the system can automatically help users to assign tasks to the CPU, so that these tasks as much as possible concurrent operation of this mechanism is called goroutine in Go
- goroutine Go language is lightweight threads implementation, when run by the Go (runtime) management. Go program will intelligently goroutine tasks reasonably assigned to each CPU.
- Go program () function starts from main main pack, when the program starts, the program will Go () function creates a default goroutine for the main.
grammar
// normal function syntax to create goroutine go function name (parameter list) // anonymous function syntax to create goroutine go func (parameter list) {function body ...} (argument list) // After go create goroutine use, function the return value is ignored
Normal function creates goroutine
main Package Import ( " FMT " " Math / RAND " " Time " ) FUNC listElem (n- int ) { for I: = 0 ; I <n-; I ++ { fmt.Println (I) } } FUNC main () { Go listElem ( 10 ) // If the main function of the code, only this one, the console will not have any output, because the main co-creation that is Chenghou Li introduced, yet had time to execute coroutine // Add the following code var the INPUT String fmt.Scanln ( the iNPUT &) // requires the user to enter any of the main characters will end }
Anonymous function creates goroutine
func main() { go func() { var times int for { times++ fmt.Println("tick", times) time.Sleep(time.Second) } } () }
Two, channel
channel basis
- A communication channel is a mechanism that allows a message sent by goroutine goroutine channel to another.
- Each channel has a special type, i.e. capable of delivering goroutine for communication between data types; eg: To send data type int channel, int can then Chan.
- Channel can be shared between the data types are: built-in type, named type, structure type, value type of a reference pointer.
- Channel follows the "FIFO" principle, guarantee the order of data transmission and reception, and at the same time only one goroutine access channel transmits messages or read messages.
grammar
// After the declaration must cooperate to make use var channel chan variable channel type // declaration channel; channel type, data type in the channel passage Examples = make (chan data type) // create channels; data element type, transmitted within the channel type // EG: var CHl Chan String CHl = the make (Chan String ) CH2: = the make (Chan int ) // create integer type of channel CH3: = the make (Chan interface {}) // Create an empty channel interface type can be stored in any format CH4: = the make (Chan Equip *) // Create Equip pointer type channels can be stored Equip * // close the passage close (ch1)
Transmitting data using channel
// syntax channel for transmitting data: "<-" operator channel tags <- value // value may be: variables, constants, expression, function return values, but the value must be consistent with the type of element type declaration channel // EG CH: = the make (Chan interface {}) // Create an empty interface channel CH <- 0 // placed into the channel 0 CH <- " the Hello World " // put into the string passage @ attached: to when transmitting data within the channel, if the recipient does not correspond to read data, the operation of transmitting data will always be blocked.
Reception data using channel
- Channel data transceiving operation is performed in two different in goroutine
- The recipient would have been blocked until the sender to send data, the same sender to the recipient also has been blocked until the read data.
- Channel can only receive a data element
// received data also use the "<-" operator Data: = <-CH // receive data blocking Data, OK: = <-CH @ nonblocking receiving data, the data is not received side, data type for the channel zero value, ok is false; in this manner will cause a high CPU occupancy, achieve the reception timeout detection can select and fit for timer channel, using generally less <-CH // receive any data, and to ignore the data received // cycle receiving for Data: = Range CH { // do something }
Unidirectional channel
var channel tags chan <- Channel type // Write Only Channel var channel tags <-chan channel type // Read Only Channel var channel chan variable channel type // readable and writable Channel // EG var WC chan <- String var RC <-chan String var CH Chan String // Close Channel Close (CH)
Unbuffered channel
Before receiving the data, not the ability to save any value of the channel. It is required to send and receive channels must be ready to complete the sending and receiving operations; if one party a channel not ready, then the party will block the channel b await passage a.
main Package Import ( " FMT " " Math / RAND " " Sync " " Time " ) var WG sync.WaitGroup FUNC the init () { rand.Seed (Time.now (). UnixNano ()) } FUNC Player (name String , Chan Court int ) { / * * hitting game process generally: Create a data channel of type int create two goroutines (players), for each shot, since the player is waiting for the first line of code in the blocking catch (from obtaining data channel), so the main ball which needs to send a first player: after starting two goroutines, there is always one preemptively removed from the data channel, then the other is blocked waiting state. and then determines whether the channel closing the channel (if closed, ok = false) If you have already closed, on behalf of the other side off the other channels lose, the current players to win, quit the game. If a judge does not hold, then select a random number and judge whether it is divisible by 22, in order to determine whether the ball (write data to the channel, let the other get [the ball]) If you can not divisible, current players lose, just close the channel and exit, right at this time to perform in the other players, when you remove the data from the channel, found channel is closed, then the victory print information. If is divisible, show the current number of shots, and writes it to the tunnel, let the other ball. The following representatives said that the main goroutine need to wait for the end to end goroutine other two main wg.Add (2) the defer wg.Done () wg.Wait () * * / the defer wg.Done () // call the function when the function exits Done in order to inform the main function, a function of the current work has been completed for { Ball, the ok: = <-court // wait for the ball IF if the channel is closed, then victory! OK { // fmt.Printf ( " Player Won% S \ n- " , name) return } // selects a random number, this number determines whether or not the ball from n-: = rand.Intn ( 100 ) IF n-% 22 is == 0 { fmt.Printf ( " Player Missed% S \ n- " , name) // close the passage, lose table Close (Court) return } // display the number of shots and number of batter + 1'd fmt.Printf ( " Player Hit% S% D \ the n- " , name, Ball) Ball++ // ball to each other Court <- Ball } } FUNC main () { // ball game Court: = the make (Chan int ) wg.Add ( 2 ) // Table: wait two goroutines Go Player ( " Juan " , Court) // start two players Go Player ( " Xiao " , Court) Court <- 1 // tee wg.Wait () // wait for the end }
Buffered & closes the passage channel
Before the data is accepted, may store one or more values of the channel, the channel of this type is not mandatory goroutine both of transmission and reception must be done simultaneously. Where blocking occurs: when the value of the channel does not need to receive acceptance of the operation is blocked; the transmission operation will be blocked when the channel is not available to accommodate the buffer to be transmitted when the values.
main FUNC () { // buffered channel: creating syntax channel instance: = make (chan channel type, cache size) bufferCh: = make (chan int , . 3 ) fmt.Printf ( " PUT Data before, Channel length:% D \ n- " , len (bufferCh)) // Check data channel size before placing bufferCh <- . 1 bufferCh <- 2 bufferCh <- . 3 Close (bufferCh) // passageway closing still can read data from the channel, but not transmitting data, errors will lead to panic, when the closed channel there is no data, to obtain data without blocking operation, will return zero fmt.Printf ( " PUT data after, channel length:% D \ n- " , len (bufferCh)) // 查看放入数据后通道大小 data1 := <-bufferCh fmt.Printf("get first data: %d\n", data1) data2 := <-bufferCh fmt.Printf("get secondly data: %d\n", data2) data3 := <-bufferCh fmt.Printf("get thirth data: %d\n", data3) data4 := <-bufferCh fmt.Printf("get next data, bur no data anymore, it is %d\n", data4) }
the difference
- Unbuffered goroutine both channels ensure data will be exchanged at the same time (data exchange, will lock the two together goroutine, only the data after a goroutine goroutine will unblock to another baton);
- Buffered unbuffered channel is based on the channel, the channel increases the storage space of a limited size, without waiting buffered receiver channel in transmitting the reception completion to complete the transmission, it does not occur clogging, until the storage space is full clogging will occur; Similarly, if the existing data channel, and receiving without blocking occurs, there is no data channel until the jam will occur.
- For chestnut: a pick-up service (unbuffered channel) and a cabinet taken delivery member (buffered channel)
- Pick-up: the sender (I) & recipient (courier), when I express ready to call the courier explained to him after the address (couriers ready) to send out the courier; if courier has not come my address, I have to block waiting; likewise, if I'm not ready courier, the courier after courier to wait for me to be ready, he can take the express.
- Express cabinet: After the sender (courier) & receiver (I), express delivery to the courier would express courier into the cabinet, and then send a text message to let me take my courier, but I do not need to immediately pick up the courier , couriers, etc. I do not need to take complete after courier to send his next delivery; only upon express cabinet is full, you can not plug express courier, and then there are vacancies will block waiting to continue into the courier; and I only when the courier cabinet and consequently will not be waiting for delivery.
channel timeout mechanism
// First, we implement and perform an anonymous A timeout function timeout: = the make (Chan BOOL , 1 ) Go FUNC () { time.sleep (1E9) // wait one second timeout <- to true } () // we then put this timeout channel utilized SELECT { Case <- ch: // read the data from the ch Case <- timeout: // has not been read from the ch data, but the data read timeout }
channel multiplexer
// disposable receiving a plurality of data channels, when operation occurs, executes the corresponding response in the case statement SELECT { case Operation 1: Response Action 1 case Operation 2: in response to operation 2 ... default : no operating conditions }
Operations | Statement Example |
---|---|
Receiving arbitrary data | case <- ch; |
Receive variables | case d := <- ch; |
send data | case ch <- 100; |