A, goroute
theory
Process: The process is the execution of a program, the system performs an independent unit of resource allocation and scheduling time in the operating system
Thread: A thread is a process of implementing entity, the CPU scheduling and allocation of the basic unit, the basic unit is smaller than the process can run independently with the
The relationship between processes and threads: one a process created and destroyed multiple threads can execute concurrently across multiple threads in the same process
Coroutine: independent stack space, shared heap space, scheduling control by the user, user-level threads on the advantages of similar nature, these calls users also realize their own thread
Coroutine relations and threads: one thread can run multiple coroutines, lightweight coroutines thread
Concurrency: the same period of performing multiple operations
Parallel: performing a plurality of operations the same time
Gorouteine Multithreading: Thread management system is operating, in kernel mode, the user switches to switch to kernel mode state needs to occur between threads
When the number of threads running on the system, the system will become very slow, the user mode thread supports the creation of a large number of threads, also known as coroutines or goroutine
Goroutine use Description
// Create goroutine FUNC the Hello () { fmt.Println ( "the Hello goroutine") } FUNC main () { Go the Hello () fmt.Prinln ( "the Terminate main the Thread") the time.sleep (time.Second) // will goroutine with the end of the main thread ends, wait lS } // start plurality goroutines FUNC Hello (I int) { fmnt.Println ( "Hello goroutines", I) } FUNC Test () { for I: = 0 <10 ; I ++ { Go Hello (I) } } FUNC main () { Test () time.sleep (time.Second) } // polynuclear control var I int FUNC Calc () {for {I ++)} FUNC main () { CPU : = runtime.NumCPU () // display the current number of CPU core FMT .Prinln ( "cpu", cpu) runtime.GOMAXPROCS (1) // only allowed in a cpu kernel for I: = 0; I <10; I ++ { Go Calc () } time.sleep (time.Hour) }
Goroutine principle of analytic
Concept: the operating system thread corresponding to a plurality of user mode goroutine, simultaneously using a plurality of threads operating system, the operating system is a many-threads goroutine
Scheduling: When the operating system needs to perform thread, one by one began to perform goroutine
Blue goroutine execution after the end of the implementation of gray, currently there are two threads in the implementation of
Call processing system
Second, the communication between goroutine
Global variables and lock synchronization
import ( "fmt" "time" "sync" ) var m make(map[int]uint64) type tesk struct { n int } func calc(t *task) { var sum uint64 sum = 1 for i := 1;i<t.n;i++ { sum *= uint64(i) } lock.Lock() m[t.n] = sum lockUnlock() } func main() { for i := 0;i<100;i++ { t := &task{n:i} go calc(t) } time.Sleep(10 * time.Second) lock.Lock() for k,v := range m { fmt.Printf("%d!=%v\n",k,v) } lock.Unlock() }
Channel (Queue pipe)
Introduction: is a queue / container FIFO essentially similar to the conduit pipe unix
Definition: The need to specify the type of the elements of courage var data type variable name chan
chan int test var var test chan String var test chan the Map [String] String var test chan stcurt var chan * stcurt // define a test address, only incoming address
Into the team: a <- 100
Dequeue: data: = <-a
test1 // FUNC main () { var Chan C int fmt.Printf ( "C V =% \ n-", C) C = the make (int Chan, 10) // If no space allocated, then the team has been blocked, running given fmt.Printf ( "C V =% \ n-", C) C <- 100 // <- C was not to discard the variable storage element Data: = <-C fmt.Println ( "Data", Data) } // test2 type struct {Student name String } FUNC main () { var stuChan Chan Student stuChan = the make (Student * Chan, 10) STU: Student = {name: "stu01"} stuChan <- STU } // Test3 FUNC Produce (Chan C int) { C <- 1000 fmt.Println ( "Produce Finished") } Consume FUNC (Chan C int) { Data: = <-C fmt.Println ( "Data", Data) } FUNC main () { var Chan C int fmt.Printf ( "C V =% \ n-", C) C the make = (chan int) Go Produce (c) Go Consume (c) the time.sleep (time.Second * 3) } // queue without the buffer, when they could have a team into the team, or the team fails
channel practice
//chan和goroutine同步 func hello(c chan bool){ fmt.Println("hello goroutine") c <- true } func main(){ var exitChan chan bool exitChan = make(chan bool) go hello(exitChan) fmt.Println("main thread terminate") <-exitChan } //单向chan func sendData(sendch chan<- int) { chan<- 表示之能入队 sendch <- 10 } func readData(sendch <-chan int) { <- chan 表示只能出队 data := <-sendch fmt.Println("data:", data) } func main() { chnl := make(chan int) go sendData(chnl) readData(chnl) } // chan Close FUNC Producer (CHNL Chan int) { for I: = 0; I <10; I ++ { CHNL <- I } Close (CHNL) // Close Chan } FUNC main () { CH: = the make (Chan int ) Go Producer (CH) for { V, OK: = <-CH IF OK == {// determines whether to false chan closed, if the pipe is closed can not determine whether the default values will always be taken to maintain the dead cycle 0 fmt.Println ( "chan Closed IS ") BREAK } fmt.Println (" Received ", V, OK) } } // for Range FUNC produer (CHNL Chan int) { for I: = 0; I <10; I ++ { CHNL <- I } Close (chnl) } func main() { ch := make(chan int) go produer(ch) for v := range ch { //chan关闭无数据后自动运行结束 fmt.Println("receive:", v) } } //带缓冲区的chanel func write( ch chan int) { for i:= 0;i<5;i++ { ch <- i fmt.Println("successfully wrote",i,"to ch") } close(ch) } func main() { ch := make(chan int,2) go write(ch) time.Sleep(2 * time.Second) for v := range ch { fmt.Println("read value",v,"from ch") time.Sleep(2 *time.SECOND) // Channel length and capacity } } func main() { ch := make(chan string,3) ch <- "naveen" ch <- "paul" fmt.Println("capacity is",cap(ch)) fmt.Println("length is",len(ch)) fmt.Println("read value",<-ch) fmt.Println("new length is",len(ch)) } //waitgroup等待一组goroutine结束,使用不带缓冲区的channel实现 func process(i int,ch chan bool) { fmt.Println("started Goroutine",i) time.Sleep(2 * time.Second) fmt.Printf("Goroutine %d ended\n",i) ch <- true } func main() { no := 3 exitChan := make(chan bool,no) for i := 0;i<no;i++ { go process(i,exitChan) } for i:= 0;i<no;i++ { <exitChan } fmt.Println ( "Executing All goroutines finshed") } // implemented using the sync-WaitGroup FUNC Process (I int, WG * sync.WaitGroup) { fmt.Println ( "Started Goroutines", I) time.sleep ( time.Second * 2) fmt.Printf ( "% D Goroutines ended \ n-", I) wg.Done (). 1-// WG } FUNC main () { NO:. 3 = var // define a WQ sync.WaitGroup wgh, defaults to 0 for I: = 0; I <NO; I ++ { wg.Add (. 1). 1 wg + Go Process (I, & wg) } wg.Wait () // only when wg down to 0 performing fmt.Println ( "Executing All goroutines Finished") } "
Third, the security thread and select between
select presentation semantics
Definition: multi-channel operation, while monitoring one or more channel, until one channel ready, if multiple chgannel which qualified at the same time ready, randomly selected to operate a similar syntax and weitch case, just get on the end of a value
server1 FUNC (CH Chan String) { time.sleep (time.Second *. 3) CH <- "Response from server1" } FUNC Server2 (CH Chan String) { time.sleep (time.Second) CH <- "Response from Server2 ") } FUNC main () { OUTPUT1: = the make (Chan String) Output2: = the make (Chan stirng) Go server1 (OUTPUT1) Go Server2 (Output2) // S1: = <-output1 // wait 3S // FMT. println ( "s1:", s1) // S2: = <-output2 // wait wait 1s then perform s1 end //fmt.Println("s2",s2) SELECT {// get the final result only of a channel S1 Case: = <-output1: fmt.Println ( "S1:", S1) Case S2:= <-output2: FMT.Prinln("s2:",s2) } }
default branch: the branch channel put the case are not ready, then execute default, used to determine whether the channel is full or empty
//test1 func server1(ch chan string) { time.Sleep(time.Second * 3) ch <- "resdponse from server1" } func server2(ch chan string) { time.Sleep(time.Second) ch <- "response from server2" } func main() { output1 := make(chan string) output2 := make(chan string) go server1(output1) go server2(output2) select { //最终只取一个channel的结果 case s1 := <- output1: fmt.Println("s1;",s1) case s2 := <-output2: fmt.Println("s2:",s2) default: fmt.Println("run default") // wait as s1 and s2, default execution moment } } //test2 func write(ch chan string) { for { select { case ch <- "hello": fmt.,Println("write succ") default: fmt.Println("channel is full") } time.Sleep(time.Millisecond * 500) } } func main() { output1 := make(chan string,10) go write(output1) for s := range.output1 { fmt.Println("recv:"s) time.Sleep(time.Second) } }