go Learning (Five): goroutine Coroutine

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 
}

        




            
Ball game 
Running Relay Race

 

 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 
}

select multiplexer pattern that can be received
Operations Statement Example
Receiving arbitrary data case <- ch;
Receive variables case d :=  <- ch;
send data case ch <- 100;

 

 

 

 

 

 

Guess you like

Origin www.cnblogs.com/hsmwlyl/p/11800410.html