This is a creation in Article, where the information may have evolved or changed.
Channels
var ch1 chan stringch1 = Make (Chan string) ch1: = Do (chan string) buf: = 100ch1: = Make (chan string, buf) Chanofchans: = ma Ke (chan chan int) Funcchan: = Chan func ()
Func main () {ch: = Make (chan string) go senddata (CH) go getData (CH) time. Sleep (1e9)}func senddata (ch chan string) {ch <-"Washington" ch <-"Tripoli" ch <-"London"}func Getdat A (ch Chan string) {var input string for {input = <-ch; Fmt. Printf ("%s", Input)}}
type empty interface {}var empty empty...data := make ([]float64, n) Res := make ([]float64, n) sem := make (chan empty, n) // semaphore ...for i, xi := range data { go func (i int, Xi float64) { res[i] = DoSomething (I,XI) sem <- empty } (I,&NBSP;XI)}for i := 0; i < n; i++ { // wait for goroutines to finish <-sem }
Func main () { stream := pump () go suck ( Stream) // shortened : go suck ( pump () ) time. Sleep (1E9)}func pump () chan int { ch := make (chan int) go func () { for i := 0; ; i++ { ch <- i } } () return ch}func suck (Ch chan int) { for { fmt. Println (<-ch) }}func suck (ch chan int) { Go func () { for v := range ch { fmt. Println (v) } } ()}
channel can only receive data and cannot be closedvar send_only chan<- intvar recv_only <-chan int // channel can only send data...var c = make (chan int) // bidirectionalgo source (c) Go sink (c) func source (Ch chan<- int) { for { ch <- 1 }}func sink (Ch <-chan int) { for { <-ch }}...// closing a channelfunc senddata (ch chan string) { ch <- "Washington" ch <- "Tripoli" ch <- "London" ch <- "Beijing" ch <- "Tokio" close (CH)}func getdata (ch chan string) { for { input, open := <-ch if !open { break } fmt. Printf ("%s ", input) }}
Select {Case u:= <-ch1: ... case v:= <-CH2: ... default://No value ready to be received ...}
If all is blocked, it waits until one can proceed
If multiple can proceed, it chooses one At Random .
When none of the channel operations can proceed and the default clause is present, Then the is executed:the the default is all runnable (that Is:ready to execute). Using a send operation in a SELECT statement with a default case guarantees that the send would be non-blocking!
|
// func tick (d duration) <- chan timeimport "Time" rate_per_sec := 10var dur duration = 1e8 // rate_per_secchrate := time. Tick (dur) // every 1/10th of a secondfor req := range requests { <- chrate // rate limit our service.method rpc calls go client. Call ("Service.method", req, ...)}
func after (d duration) <-chan timefunc main () { tick := time. Tick (1e8) boom := time. After (5e8) for { select { case <-tick: fmt. Println ("tick.") case <-boom: fmt. Println ("boom!") return default: &nbsP;fmt. Println ("&NBSP;&NBSP;&NBSP;&NBSP;.") time. Sleep (5e7) } }}
Func Server (Workchan <-chan *work) {for-Work: = Range Workchan {go-safelydo (work)}}func-Safelydo (work *work) {defer func () {if err: = Recover (); Err! = nil {log. Printf ("Work failed with%s in%v:", err, Work)}} () does (work)}
tasks And worker Processes
Type pool struct { mu sync. Mutex tasks []task}func worker (Pool *pool) { for { pool. Mu.lock () // begin critical section: task := pool. tasks[0] // take the First task pool. Tasks = pool. tasks[1:] // update the pool // end critical section pool. Mu.unlock () process (Task) }}
-
rule-use locking (mutexes) When: caching Information in a shared data Structure; holding state information;
-
rule-use channels When: communicating asynchronous Results; Distributing units of Work; passing ownership of data;
lazy generator
Var resume chan intfunc integers () chan int { yield := make (Chan int) count := 0 go func () { for { yield <- count count++ } } () return yield}func generateinteger () int { return <-resume}func main () { resume = integers () fmt. Println (Generateinteger ()) //=> 0 fmt. Println (Generateinteger ()) //=> 1}
benchmarking goroutines
Func main () { fmt. Println ("Sync", testing. Benchmark (Benchmarkchannelsync). String ()) fmt. Println ("Buffered", testing. Benchmark (benchmarkchannelbuffered). String ())}func benchmarkchannelsync (b *testing. B) { ch := make (chan int) go func () { for i := 0; i < b.N; i++ { ch <- i } close (CH) } () for _ = range ch { }}func Benchmarkchannelbuffered (B *teSting. B) { ch := make (chan int, 128) go func () { for i := 0; i < b.N; i++ { ch <- i } close (CH) } () for _ = range ch { }}// Output:// Windows: N Time 1 op Operations per sec// sync 1000000 2443 ns/op --> 409 332 / s// buffered 1000000 4850 ns/op --> 810 477 / s
/* mutexes */func (s semaphore) Lock () {S.P (1)}func (s semaphore) Unlock () {s.v (1)}/* signal-wait */func (s Semap Hore) Wait (n int) {S.P (n)}func (s semaphore) Signal () {s.v (1)}