Some tips for Go channel

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

1. A channel that has been closed will never block. Once a channel is closed, it is no longer possible to send data to the channel, but it can still try to get the value from the channel.

2. The channel that has been closed is returned in real time.


Package Mainimport ("FMT" "Sync" "Time") Func main () {const-n = 100000finish: = Make (chan bool) var-Done sync. Waitgroupfor I: = 0; I < n; i++ {done. ADD (1) go func () {select {case <-time. After (1 * time. Hour): Case <-finish:}done. Done ()} ()}t0: = time. Now () Close (finish) is done. Wait () fmt. Printf ("Waited%v for%d goroutines to Stop\n", time. Since (t0), N)}


When the finish channel is closed, it returns immediately. Then all waits to receive time. The SELECT statement for the after channel or finish Goroutine is completed immediately, and Goroutine is called done. Done () to reduce the Waitgroup counter after exiting. This powerful mechanism makes it possible to send signals to them without having to know any details of the unknown number of goroutine, without worrying about deadlocks.

When close relies on the message mechanism to close the channel, and no data is sent and received, the definition of finish as type Chan struct{} means that the channel has no data and is only interested in its closed properties. i.e.: Finish: = Make (chan struct{})

3. When the value of the channel has not been initialized or is assigned nil, it is always blocked.

Waitmany (), once a value is received, the reference to a or B is set to nil. When the nil channel is part of a SELECT statement, it is actually ignored, so setting a to nil removes it from select, leaving only b waiting for it to be closed, and then exiting the loop.

4. Various techniques of slice append function

Add Slice a = append (A, B, C, D)//Add slice B to slice aa=append (A, b ...) Copy Slice B: = make ([]int, Len (a)) copy (b, a)//delete the specified position element [i:j]a = append (A[:i], a[j:] ...) Delete Nth Element a = append (A[:n], a[n+1:] ...) Expand n Empty Elements a = append (A, make ([]int, N) ...) Insert J empty Element a = append (A[:i], append (Make ([]int, J), A[i:] In the first place ...) ...) Insert element in the i position xa = append (A[:i], append ([]int{x}, A[i:] ...) ...) Insert a slice in i position a = append (A[:i], append ([]int{x, y}, A[i:] ...) ...)

Where the delete operation is overwrite, and the insert operation needs to be careful not to overwrite the insertion position and subsequent elements.

5. Questions about string and []byte, []rune-to-cross conversion:

str: = "Hello World"   SLI: = []rune (str)   []rune is the go built-in function that converts the string into UTF8 encoding to {h,e,l,l,o, world, bounds} corresponding number { 104,101,108,108,111,19990,30028}   byt: = []byte (str)   []byte is a go built-in function that converts str to a byte slice { 104,101,108,108,111,228,184,150,231,149,140} for   _,c: = Range str{     println (c)   }   len (str) return    One Len returns a string of byte-length   characters in the go, which can be ascii/Chinese    . S: = ' You '   string (SLI)/string (byt) all return "Hello World"       string () is a go built-in function either []rune or []byte] can return the corresponding string through the string () function
6. in the use of multiple goroutine printing content, often because the use of Chan inappropriate to cause the main thread did not wait for the completion of all other goroutine complete and hurried to the issue, resulting in the printing content is not complete, here is a situation to explain.

The package main import (         "FMT"        "runtime")//is superimposed from 1 to 100 million cycles and prints the results. Func print (c chan bool, n int) {         x: = 0 for         i: = 1; I <= 100000000; i++ {                 x + = i         }         fmt. PRINTLN (n, x)         if n = = 9 {                 c <-true        }}   func main () {         //Use multicore Run program         runtime. Gomaxprocs (runtime. NUMCPU ())         c: = Make (chan bool) for         I: = 0; i <; i++ {                 go print (c, i)         }         <-c         fmt. Println ("Done.")}
This code is logically plausible, but it is a very OpportunisticThe implementation of the 10th goroutine, according to the in hasteIt is considered that the previous 9 goroutine have been executed. If you will ' Runtime. Gomaxprocs (runtime. NUMCPU ()) 'If you use a single core to run the program, you will get the results you expect, but if you are using multicore, this is of the wrongGoroutine are independent of each other and may cause several of these goroutine to yield time slices to the CPU to perform other goroutine during execution. So, we can not rely onThe execution result of the 10th goroutine to determine the operation of the program.

Solution one: Take advantage of Chan's caching mechanism

The package main import (         "FMT"        "runtime")//is superimposed from 1 to 100 million cycles and prints the results. Func print (c chan bool, n int) {         x: = 0 for         i: = 1; I <= 100000000; i++ {                 x + = i         }         fmt. PRINTLN (n, x)         C <-true}   func main () {     //using multi-core run program         runtime. Gomaxprocs (runtime. NUMCPU ())         c: = Make (chan bool, ten) for         I: = 0; i <; i++ {                 go print (c, i)         } for         I: = 0; I &l T 10; i++ {                 <-c         }         fmt. Println ("Done.")}
Solution Two: Waitgroup using the Sync pack
The package main import (     "FMT" "    runtime" "    Sync")//is superimposed from 1 to 100 million cycles and prints the results. Func Print (WG *sync. Waitgroup, n int) {     x: = 0 for     i: = 1; I <= 100000000; i++ {         x + = i     }     fmt. PRINTLN (n, x)     //identifies a task completion     WG. Done ()}   func main () {     //using multi-core run program     runtime. Gomaxprocs (runtime. NUMCPU ())     //Create wait Group     WG: = Sync. waitgroup{}     //Set the number of objects to wait for     WG. ADD ()     for I: = 0; i <; i++ {         go print (&WG, i)     }     //wait for all tasks to complete the     WG. Wait ()     FMT. Println ("Done.")}

7. Golang HTTP request Optimization

To determine whether the URL is valid//does not start with/HTTP, add http://if!strings. Hasprefix (Feed, "http") {feed = "//" + feed}//determine if the URL is reasonable host, err: = URL. Parserequesturi (FEED) if err! = Nil {}//Determines whether it can resolve to the corresponding host record _, err = net. Lookupip (host. Host) If Err! = Nil {}//Requests data client to host: = &http. client{Transport: &http. transport{Dial:func (netw, addr string) (net. Conn, error) {deadline: = time. Now (). ADD (Ten * time. Second) C, err: = Net. Dialtimeout (NETW, addr, 5*time.             Second)//Connection time-out if err! = Nil {return nil, err} c.setdeadline (Deadline) Return c, nil},},}req, err: = http. Newrequest ("GET", feed, nil) if err! = Nil {}//data transfer compression//tells the host to support Gzip data request back after Ungzipreq. Header.set ("User-agent", "mozilla/5.0" (compatible; ujcspider/0.1; +HTTP://UJIECAO.COM/HELP) ") req. Header.set ("accept-encoding", "gzip") resp, err: = client. Do (req) if err! = nil {}defer resp. Body.close () var reader io. Readcloserswitch resp. Header.get ("Content-encodiNg ") {case" gzip ": reader, _ = gzip. Newreader (resp. Body) Defer reader. Close () Default:reader = resp. Body}


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.