Package main Import ( "FMT" "Math / RAND" "OS" "Runtime" "Sync" "Sync / Atomic" "Time" ) type Scenario struct { the Name String the Description [] String Examples [] String runExample FUNC () } var Scenario & = {S1 the Name: "S1", the Description: [] {String "simple tasks executed concurrently", }, Examples: [] {String "rear concurrent requests such an interface", }, runExample: RunScenario1, } & Scenario S2 = {var the Name: "S2", the Description:[] {String "predetermined time duration high concurrency model" }, Examples: [] {String "Within a predetermined time, sustained high concurrent requests backend service to prevent the service infinite loop", }, runExample: RunScenario2, } var S3 = & Scenario { the Name: "S3", String {[]: the Description "large amount of data based on model of concurrent tasks, the pool goroutine worker ", }, Examples: [] {String " such as technical support to give a customer deletes several TB / GB file ", }, runExample: RunScenario3, } var s4 = {& Scenario the Name : "S4", the Description: [] String { "wait for asynchronous execution result of the task (goroutines + SELECT + Channel)", }, Examples: [] String { "", }, runExample: RunScenario4, } var S5 = & Scenario { the Name : "s5","s5", Description: []string{ "The timing of the feedback result (Ticker)", }, Examples: [] {String "such as testing performance of the interface to upload, to give real-time indicators: throughput, IOPS, the success rate", }, runExample: RunScenario5, } var Scenarios [] * Scenario FUNC the init () { Scenarios = the append (scenarios, S1) scenarios = the append (scenarios, S2) scenarios = the append (scenarios, S3) scenarios = the append (scenarios, S4) scenarios = the append (scenarios, S5) } // concurrency and common synchronization scenario func main ( ) { IF len (os.Args). 1 == { fmt.Println ( "Please choose a scene ==>") for _, SC: = Range scenarios { fmt.Printf ( "scene:% s,", sc. name) printDescription (sc.Description) } return } for _, Arg: = Range os.Args [. 1:] { sc := matchScenario(arg) if sc != nil { printDescription(sc.Description) printExamples(sc.Examples) sc.RunExample() } } } func printDescription(str []string) { fmt.Printf("场景描述: %s \n", str) } func printExamples(str []string) { fmt.Printf("场景举例: %s \n", str) } func matchScenario(name string) *Scenario { for _, sc := range Scenarios { if sc.Name == name { return sc } } return nil } var doSomething = func(i int) string { time.Sleep(time.Millisecond * time.Duration(10)) fmt.Printf("Goroutine %d do things .... \n", i) return fmt.Sprintf("Goroutine %d", i) } var takeSomthing = func(res string) string { time.Sleep(time.Millisecond * time.Duration(10)) tmp := fmt.Sprintf("Take result from %s.... \n", res) fmt.Println(tmp) return tmp } // 场景1: 简单并发任务 func RunScenario1() { count := 10 var wg sync.WaitGroup for i := 0; i < count; i++ { wg.Add(1) go func(index int) { defer wg.Done() doSomething(index) }(i) } wg.Wait() } // 场景2: 按时间来持续并发 func RunScenario2() { timeout := time.Now().Add(time.Second * time.Duration(10)) n := runtime.NumCPU() waitForAll := make(chan struct{}) done := make(chan struct{}) concurrentCount := make(chan struct{}, n) for i := 0; i < n; i++ { concurrentCount <- struct{}{} } go func() { for time.Now().Before(timeout) { <-done concurrentCount <- struct{}{} } waitForAll <- struct{}{} }() go func() { for { <-concurrentCount go func() { doSomething(rand.Intn(n)) done <- struct{}{} }() } }() <-waitForAll } // 场景3:以 worker pool 方式 并发做事/发送请求 func RunScenario3() { numOfConcurrency := runtime.NumCPU() taskTool := 10 jobs := make(chan int, taskTool) results := make(chan int, taskTool) var wg sync.WaitGroup // workExample workExampleFunc := func(id int, jobs <-chan int, results chan<- int, wg *sync.WaitGroup) { defer wg.Done() for job := range jobs { res := job * 2 fmt.Printf("Worker %d do things, produce result %d \n", id, res) time.Sleep(time.Millisecond * time.Duration(100)) results <- res } } for i := 0; i < numOfConcurrency; i++ { wg.Add(1) go workExampleFunc(i, jobs, results, &wg) } totalTasks := 100 wg.Add(1) go func() { defer wg.Done() for i := 0; i < totalTasks; i++ { n := <-results fmt.Printf("Got results %d \n", n) } close(results) }() for i := 0; i < totalTasks; i++ { jobs <- i } close(jobs) wg.Wait() } // 场景4: 等待异步任务执行结果(goroutine+select+channel) func RunScenario4() { sth := make(chan string) result := make(chan string) go func() { id := rand.Intn(100) for { sth <- doSomething(id) } }() go func() { for { Result <- takeSomthing (<- STH) } }() SELECT { Case C: = <-result: fmt.Printf ( "% S Got Result", C) Case <-time.After (time.Duration (30 * time.Second) ): fmt.Errorf ( "specified time not result") } } var doUploadMock = FUNC () {BOOL time.sleep (time.Millisecond time.Duration * (100)) n-: = rand.Intn (100) n-IF> {50 return to true } the else { return to false } } // scenario 5: feedback result (Ticker) timing // test performance of the interface to upload, to give real-time indicators: throughput, the success rate func RunScenario5 () { totalSize: Int64 = (0) The totalCount: = Int64 (0) totalErr: = Int64 (0) concurrencyCount: = runtime.NumCPU () STOP: = the make (Chan struct {}) fileSizeExample: = Int64 (10) timeout := 10 // seconds to stop go func() { for i := 0; i < concurrencyCount; i++ { go func(index int) { for { select { case <-stop: return default: break } res := doUploadMock() if res { atomic.AddInt64(&totalCount, 1) atomic.AddInt64(&totalSize, fileSizeExample) } else { atomic.AddInt64(&totalErr, 1) } } }(i) } }() t := time.NewTicker(time.Second) index := 0 for { select { case <-t.C: index++ tmpCount := atomic.LoadInt64(&totalCount) tmpSize := atomic.LoadInt64(&totalSize) tmpErr := atomic.LoadInt64(&totalErr) fmt.Printf("吞吐率: %d,成功率: %d \n", tmpSize/int64(index), tmpCount*100/(tmpCount+tmpErr)) if index > timeout { t.Stop() close(stop) return } } } }