二十三 管道

2021-10-04 14:52:16 字數 4653 閱讀 1065

在go語言中可以通過chan來定義管道,可以通過操作符<-和->對管道進行讀取和寫入操作

通過管道維護例程狀態:

使用make函式初始化,make(chan type)/make(chan type, len),不帶len引數的用於建立無快取區的管道,使用len建立指定緩衝區長度的管道

讀寫管道

可通過操作符<-和->對管道進行讀取和寫入操作,當寫入無緩衝區管道或由緩衝區管道已滿時寫入則會阻塞直到管道中元素被其他例程讀取。同理,當管道中無元素時讀取時也會阻塞到管道被其他例程寫入元素

package main

import

"fmt"

//管道

func

main()

()fmt.

println

("open"

) fmt.

println

(<- notice)

fmt.

println

("close"

)}

package main

import

("fmt"

"runtime"

"time"

)func

printcharts

(name int

,channel chan

int)

channel <- name

fmt.

println

("寫入"

,name)

}func

main()

for i:=

0;i<

10;i++

fmt.

println

(" over"

) time.

sleep

(time.second *10)

}

管道是宣告需要指定管道存放資料的型別,管道原則可以存放任何型別,但只建議用於存放值型別或者只包含值型別的結構體。在管道宣告後,會被初始化為nil

唯讀/只寫管道

可以在函式引數時宣告管道為chan<-或chan->,表示管道只寫或唯讀

package main

import

("fmt"

"time"

)func

main()

(rchannel)

gofunc

(a chan

<-

int)

(wchannel)

wchannel<-

2 fmt.

println

(<-rchannel)

time.

sleep

(time.second*3)

}

關閉管道

可通過close函式關閉管道,關閉後的管道不能被寫入,當讀取到最後乙個元素後可通過讀取的第二個引數用於判斷是否結束

遍歷管道

可以通過for-range進行遍歷

package main

import

"fmt"

func

main()

}

select-case

當寫入無緩衝區管道或由緩衝區管道已滿時寫入則會阻塞直到管道中元素被其他例程讀取。同理,當管道中無元素時讀取時也會阻塞到管道被其他例程寫入元素,若需要同時對多個管道進行監聽(寫入或讀取),則可以使用select-case語句

package main

import

"fmt"

func

main()

()gofunc()

()select

}

package main

import

"fmt"

func

main()

()gofunc()

()select

}

超時機制-可以通過select-case實現對執行操作超時的控制

select-case語句監聽每個case語句中管道的讀取,當某個case語句中管道讀取成功則執行對應子語句

go語言time包實現了after函式,可以用於實現超時機制,after函式返回乙個唯讀管道

select-case語句

package main

import

("fmt"

"time"

)func

main()

}

package main

import

("fmt"

"math/rand"

"time"

)func

main()

()//go func() ()

select

}

sync包提供了同步原語,常用結構體有:

sync.mutex:互斥鎖

sync.rwmutex:讀寫鎖

sync.cond:條件等待

sync.once:單次執行

sync.map:例程安全對映

sync.pool:物件池

sync.waitgroup:組等待

(1)sync.map:例程安全對映

package main

import

("fmt"

"sync"

)func

main()

if value,ok:= users.

load(20

);ok

users.

delete(10

)//刪除這個key value也就沒了

if value,ok := users.

load(10

);ok

}

(2)sync.once:單次執行

package main

import

("fmt"

"sync"

)func

main()

)}}

(3)sync.pool:物件池

package main

import

("fmt"

"sync"

)func

main()

}//在獲取的時候會建立

x := pool.

get(

) fmt.

println

(x)//獲取完之後將元素放回池

pool.

put(x)

//再次獲取 從池子中拿出來

x = pool.

get(

)//繼續獲取就需要重新再建立乙個

x = pool.

get(

)print()

fmt.

println()

}

package main

import

("fmt"

"sync"

)//new 是乙個函式返回值是乙個介面

//自定義型別

type new func()

inte***ce

type a inte***ce

type pool struct

new new

}func

newpool

(size int

,new new)

*pool

,size)

for i :=

0;ireturn

&pool

}func

(p *pool)

get(

)inte***ce

else

}func

(p *pool)

put(obj inte***ce

)func

main()

) x := pool.

get(

) fmt.

println

(x) pool.

put(x)

x = pool.

get(

) x = pool.

get(

)print()

fmt.

println()

}

runtime包提供了與go執行時系統互動的操作,常用函式:

runtime.gosched(): 當前goroutine讓出時間片

runtime.goroot(): 獲取go安裝路徑

runtime.numcpu(): 獲取可使用的邏輯cpu數量

runtime.gomaxprocs(1):設定當前程序可使用的邏輯cpu數量

runtime.numgoroutine(): 獲取當前程序中goroutine的數量

package main

import

("fmt"

"runtime"

)func

main()

隨筆 二十三

1.gradle 完a整指南 android 2.android gradle 外掛程式 3.0 挖坑日記 3.android效能優化全方面解析 4.android studio 3.2新功能特性 5.重新認識 androidstudio 和 gradle,這些都是你應該知道的 6。美團外賣andr...

演算法(二十三)

1 給定乙個整數陣列nums,找到乙個具有最大和的連續子陣列 子陣列最少包含乙個元素 返回其最大和。public int maxsubarray int nums return maxsum 複雜度分析 public int maxsubarray int nums return maxsum 2 ...

Linuxc基礎 二十三

位運算子 1 位操作需要用巨集定義好後在使用。2 如果位操作符 和 3 位運算不能用於基本型別是有符號的運算元上。4 一元減運算子不能用在基本型別無符號的表示式上,除非在使用之前對兩個運算元進行大小判斷,且被減數必須大於減數。左移和右移是雙目運算子。和 作為字首是先自加或自減然後再做別的運算。和 作...