這個例子是從go原始碼src/pkg/net/rpc/server_test.go擷取出來的
func benchmarkendtoendasync(dial func() (*client, error), b *testing.b)
// asynchronous calls
args := &args
procs := 4 * runtime.gomaxprocs(-1)
send := int32(b.n)
recv := int32(b.n)
var wg sync.waitgroup
wg.add(procs)
gate := make(chan bool, maxconcurrentcalls)
res := make(chan *call, maxconcurrentcalls)
b.starttimer()
for p := 0; p < procs; p++
}()go func()
if atomic.addint32(&recv, -1) == 0
}wg.done()
}()}
wg.wait()
}
這個**用來對rpc的客戶端go函式進行壓力測試。
這裡有幾個地方值得揣摩下:
先使用startserver(這個函式裡面具體是開啟了乙個routine)進行伺服器服務。然後在每個測試用例中啟動server,如果是benchtest的話記得這裡的timer要在啟動伺服器行為之後再開啟。
wg變數是sync.waitgroup型別,add增加計數,done減少計數,wait進行阻塞等待,等計數減為0的時候再停止阻塞。
這裡如果不使用waitgroup進行wait阻塞的話,主routine會先於次routine先結束。會導致程式提早退出。
因此這裡也給出了乙個測試用例中測試非同步函式的方法。就是使用waitgroup
看起來gate好像是沒什麼用啊,如果去掉gate呢?有可能會出現「rpc: discarding call reply due to insufficient done chan capacity」
這個gate完全是因為client.go這個函式,rpc包的client.go是非同步的呼叫,雖然是非同步呼叫,這個非同步呼叫的最後乙個done引數是乙個channel buffer。
當client.go進行完rpc呼叫後,將訊號傳入這個channel buffer。但是這個channel buffer卻是不會阻塞的。
具體看原始碼:
這裡select加了個default分支,說明了done是非阻塞的。看注釋,作者認為這個buffer的大小容量應該由呼叫者來保證。rpc包並不保證容量大小。
方法有個兩個:
這個方法就是gate的使用原因了。只有gate容量有剩餘的時候才會容許呼叫client.go
在這個例子中,bench的channel最大只會是b.n,所以,如果我們分配的res的channel buffer大小為b.n也能解決這個問題。
這個方法導致的效果就是bench的時間變快了,但是mem分配增加了。
因為這裡會有多個routine會對send和recive進行操作,這裡就需要保證原子性。
多個併發routine對乙個共享變數進行操作有兩種方法,channel和鎖。
這裡當然使用channel也能起到原子操作的效果。sync包的atomic和sync的mutex都是鎖的方式。
所以說這裡其實可以使用channel,mutex,atomic三種方法。
bench test在執行前自身會呼叫runtime.gomaxprocs進行多核的設定,然後再每個處理器中並行執行測試。
這裡的runtime.gomaxprocs(-1)是獲取你要跑的cpu核數,這個核數是根據bench test的 -test.cpu設定的。具體可以看下src/testing/testing.go parsecpulist。在沒有設定過gomaxprocs和test.cpu的情況下,這裡的runtime.gomaxprocs就預設是1。
你可以使用-test.cpu 1,2,4來設定你的壓力測試用例是有幾個cpu,每個cpu是幾核的。
這裡的procs設定為處理器核數的4倍就是為了測試routine能分配遠大於核數的個數,這樣每個核承擔的goroutine能大於1。
上面的for迴圈就是保證起的routine數是足夠的。
golang,使用型別斷言的乙個例子
type spotprice struct var pricei inte ce var err error pricei,err db.getspotprice realprice.productid,1,1 if err nil value pricei.price.spotprice real...
LineDDA的乙個例子
unit unit1 inte ce uses windows,messages,sysutils,variants,classes,graphics,controls,forms,dialogs,extctrls,stdctrls,buttons type tfmmain class tform ...
SQL GROUP CONCAT的乙個例子
我有乙個這樣的資料庫 user info 現在有乙個需求是把這樣 9 條記錄按照 username 來 group 成3條記錄 目標 shu female 201 lee male 202 yuki female 181 如果用select from user info group by usern...