Механизам блокирања цевовода Го и кореутина за проналажење простих бројева

Mechanism Go Pipeline Blocking



Механизам за блокирање цевовода

  • Случај:
intChan := make(chan int, 10) exitChan := make(chan bool, 1) go writeData(intChan) go readData(intChan, exitChan) for { _, ok := <-exitChan if !ok { break } }
  • Питање: Ако се одјавите, идите реадДата (интЦхан, екитЦхан), шта ће бити са програмом?
    • Одговор: Ако само пишете податке у цев, Без читања , Доћи ће до блокирања и мртве браве, разлог је тај што је капацитет интЦхан 10, а код вритеДата ће написати 50 података, па ће бити блокиран у вритеДата цх<-i
  • Ако компајлер (извршавање) утврди да цијев има само записе, али нема читања, цијев ће бити блокирана.
  • Учесталост цијеви за писање и цијеви за читање су недосљедне, није важно.

Короутина за просте бројеве

  • потражња:
    • Који су прости бројеви међу бројевима потребним за бројање 1-80000?
  • анализа идеје:
    • Традиционална метода је употреба петље да би се утврдило да ли је сваки број прост или не.
    • Користите паралелни / паралелни приступ, Задатак бројања простих бројева доделите вишеструким (4) гороутинама да их довршите , Кратко време за извршавање задатка.
  • Дијаграм анализе:

  • Шифра:
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') }
  • Пресретните неке резултате трчања:



Тестирајте ефикасност кореутине за проналажење простих бројева

  • Користите тест ефикасности короутине:
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') }
  • Излазни резултат:



  • Тест ефикасности традиционалне методе:
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) }
  • Излазни резултат