go-channel實踐1

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

        某些資訊從舊的資源集區中取出來,經過一些加工處理,再放入新的資源集區中,這個過程如果按傳統的方式就是採用完全串列的方式效率會很低,粒度太粗了,具體的粒度可以細化以每次所取的單位資源為粒度。

有一個資源集區儲存這person的資訊,將每個person從中取出來,之後進行一些處理,再存到新的資源集區中,這裡用oldarray以及newarray來類比舊的和新的資源集區:

代碼如下:


type Person struct {       name string       age  int       addr string}var oldpersonarray = [5]Person{}var newpersonarray = [5]Person{}type PersonHandler interface {       Batch(origs <-chan Person) <-chan Person       Handle(orig *Person)}//struct 實現了personhandler 介面type PersonHandlerImpl struct{}//從origs接收資訊 處理之後再返回給新的channelfunc (handler PersonHandlerImpl) Batch(origs <-chan Person) <-chan Person {       dests := make(chan Person, 100)       go func() {              for {                     p, ok := <-origs                     if !ok {                            close(dests)                            break                     }                     handler.Handle(&p)                     log.Printf("old value : %v\n", p)                     //time.Sleep(time.Second)                     dests <- p              }       }()       return dests}//這裡要使用引用傳遞func (handler PersonHandlerImpl) Handle(orig *Person) {       orig.addr = "new address"}func getPersonHandler() PersonHandler {       return &PersonHandlerImpl{}}//print the oldpersonarray into the chan<-Personfunc fetchPerson(origs chan<- Person) {       for _, v := range oldpersonarray {              fmt.Printf("get the value : %v \n", v)              time.Sleep(time.Second)              origs <- v       }       close(origs)}//fetch the value from the channel and store it into the newpersonarrayfunc savePerson(dest <-chan Person) <-chan int {       intChann := make(chan int)       go func() {              index := 0              for {                     p, ok := <-dest                     if !ok {                            break                     }                     time.Sleep(time.Second)                     log.Printf("new value transfer %v \n", p)                     newpersonarray[index] = p                     index++              }              intChann <- 1       }()       return intChann}func init() {       //使用range的話是值傳遞 這裡要給oldpersonarray賦值進來       tmplen := len(oldpersonarray)       for i := 0; i < tmplen; i++ {              oldpersonarray[i].addr = "old address"              oldpersonarray[i].age = i              oldpersonarray[i].name = strconv.Itoa(i)       }       log.Printf("first print init value : %v\n", oldpersonarray)}func main() {       handeler := getPersonHandler()       origs := make(chan Person, 100)       dests := handeler.Batch(origs)       go func() { fetchPerson(origs) }()       // 不加go func的話 要等這句執行完 才能執行下一句       // 則orgis資訊都輸出 完全關閉掉 這個時候 從dest接收資訊的語句才開始執行       // 所以不會動態輸出 這句加上go func的話 就會沒隔 1s 動態輸出       // 如果將fetchPerson 再往前面放一句 則old value也不會動態輸出       //fetchPerson(origs)       sign := savePerson(dests)       log.Println(<-sign)       log.Printf("last print new value : %v \n", newpersonarray)}

  • 首先聲明一個 PersonHandler 的介面,之後聲明一個struct PersonHandlerImpl 將介面中的兩個方法都實現了,init函數用於進行oldarray的初始化工作。注意為了減少出錯,內部的函數在方聲明的時候都是單向的channel。
  • 1,2 fetchperson從oldarray中區資料,並把資料存到origs channel中,注意最後取完資料到通道之後,要由發送方將channel關閉,否則可能造成deadlock。注意在main函數中,如果fech操作沒有放到一個goroutine中來執行,就仍然是串列的,相當於是把資料都放入到channel中,另一端才開始取,沒發揮出並發的優勢。
  • 3,4 Batch函數將person資訊從origs中取出來,進行處理後,同時傳到dests中,最後將dests返回,注意這裡不是全部傳入之後才將dests返回,而是新啟動一個goroutine執行傳入操作,同時將dests返回,注意要主動關閉channel。
  • 5 savePerson操作接收一個<-chann 之後從中接受person資訊,將值寫入到新的資源集區中,最後全部寫入結束之後,傳一個sign channel給主進程,結束。
  • 總結,在需要動態輸出資訊的時候,goroutine往往是和channel結合在一起使用。最常見的用法是,一個goroutine負責向channel中寫入資料,之後將channel返回,由其他進程取出資訊。比如之前寫過的一些websocket從前台接受資訊,幕後處理資訊之後再動態返回給前台打出結果的模型,就和這個差不多,總之具體的非同步執行流程要理清楚,都有哪些channel,負責傳遞的資訊分別是什麼。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.