Ang mekanismo ng pagharang sa pipeline ng Go at ang coroutine upang makahanap ng pangunahing mga numero

Mechanism Go Pipeline Blocking



Mekanismo sa pagharang ng pipeline

  • Kaso:
intChan := make(chan int, 10) exitChan := make(chan bool, 1) go writeData(intChan) go readData(intChan, exitChan) for { _, ok := <-exitChan if !ok { break } }
  • Tanong: Kung mag-log out ka go readData (intChan, exitChan), ano ang mangyayari sa programa?
    • Sagot: Kung sumulat ka lamang ng data sa tubo, Nang hindi nagbabasa , Magkakaroon ng pagharang at patay na lock, ang dahilan ay ang kapasidad ng intChan ay 10, at ang code na magsulatData ay magsusulat ng 50 data, kaya't mai-block ito sa writeData ch<-i
  • Kung nahahanap ng tagatala (run) na ang isang tubo ay may nagsusulat lamang ngunit walang nagbabasa, mai-block ang tubo.
  • Ang dalas ng magsulat ng tubo at ang nabasa na tubo ay hindi naaayon, hindi mahalaga.

Coroutine para sa pangunahing mga numero

  • demand:
    • Kabilang sa mga bilang na kinakailangan upang mabilang ang 1-80000, alin ang pangunahing mga numero?
  • pagsusuri ng ideya:
    • Ang tradisyunal na pamamaraan ay ang paggamit ng isang loop upang matukoy kung ang bawat numero ay kalakhan o hindi.
    • Gumamit ng kasabay / parallel na diskarte, Italaga ang gawain ng pagbibilang ng mga pangunahing numero sa maraming (4) mga goroutine upang makumpleto , Maikling oras upang makumpleto ang gawain.
  • Pagsusuri diagram:

  • Code:
package main import ( 'fmt' ) //Put 1-8000 numbers into intChan func putNum(intChan chan int) { for i := 1 i <= 80000 i++ { intChan<- i } //Close intChan close(intChan) } // Take out the data from intChan and determine whether it is a prime number, if it is, then/put it into primeChan func primeNum(intChan chan int, primeChan chan int, exitChan chan bool) { var flag bool // for { num, ok := <-intChan //intChan can't get it... if !ok { break } flag = true //assume it is a prime number // Determine if num is a prime number for i := 2 i < num i++ { if num% i == 0 {//Indicates that num is not a prime number flag = false break } } if flag { //Put this number into primeChan primeChan<- num } } fmt.Println('There is a primeNum coroutine because it cannot get data, exit') exitChan<- true } func main() { intChan := make(chan int , 1000) primeChan := make(chan int, 20000)//Put the result //Identify the exiting pipeline exitChan := make(chan bool, 4) //Open a coroutine and put 1-8000 numbers into intChan go putNum(intChan) //Open 4 coroutines, take out the data from intChan, and judge whether it is a prime number, if it is, put it in primeChan for i := 0 i < 4 i++ { go primeNum(intChan, primeChan, exitChan) } go func(){ for i := 0 i < 4 i++ { <-exitChan } //When we take out 4 results from exitChan, we can safely close primeChan close(primeChan) }() //Here the main thread, for processing //Traverse primeChan and take out the result for { res, ok := <-primeChan if !ok{ break } //Output the result fmt.Printf('prime number=%d ', res) } fmt.Println('main thread exits') }
  • Maharang ang ilang mga tumatakbo na resulta:



Subukan ang kahusayan ng coroutine para sa paghahanap ng mga pangunahing numero

  • Gumamit ng pagsubok sa kahusayan ng coroutine:
func main() { intChan := make(chan int , 1000) primeChan := make(chan int, 20000)//Put the result //Identify the exiting pipeline exitChan := make(chan bool, 4) // 4 start := time.Now().Unix() //Open a coroutine and put 1-8000 numbers into intChan go putNum(intChan) //Open 4 coroutines, take out the data from intChan, and judge whether it is a prime number, if it is, put it in primeChan for i := 0 i <4 i++ { go primeNum(intChan, primeChan, exitChan) } //Here our main thread, for processing go func(){ for i := 0 i < 4 i++ { <-exitChan } end := time.Now().Unix() fmt.Println('Time-consuming to use coroutine=', end-start) //When we take out 4 results from exitChan, we can safely close primeChan close(primeChan) }() //Traverse our primeChan and take the result out for { _, ok := <-primeChan if !ok{ break } //Output the result //fmt.Printf('prime number=%d ', res) } fmt.Println('main thread exits') }
  • Resulta ng output:



  • Tradisyunal na pagsubok sa kahusayan ng pamamaraan:
package main import ( 'time' 'fmt' ) func main() { start := time.Now().Unix() for num := 1 num <= 80000 num++ { flag := true //assume it is prime // Determine if num is a prime number for i := 2 i < num i++ { if num% i == 0 {//Indicates that num is not a prime number flag = false break } } if flag { //Put this number into primeChan //primeChan<- num } } end := time.Now().Unix() fmt.Println('Ordinary method takes time=', end-start) }
  • Resulta ng output