gocoroutine
gocoroutine copied to clipboard
task 调度执行存在并发问题
benchmark_test.go
package gocoroutine
import (
// "fmt"
"sync"
"testing"
)
var k int = 0
var m int = 0
func msgProc_benchmark(fc FlowControl) {
//fmt.Println("msg 1")
fc.Yield(dbProc_benchmark)
}
func dbProc_benchmark(fc FlowControl) {
//fmt.Println("db 1")
// msgid := fc.Params().(int)
k++
}
func recvProc_benchmark(sch *Scheduler) {
for i := 0; i < 100000; i++ {
sch.AddTask(msgProc_benchmark, i)
}
}
func TestBenchmark(t *testing.T) {
sch := NewScheduler()
sch.Start()
recvProc_benchmark(sch)
sch.Exit()
println("final k:\n", k)
}
func traditionalLogic(wg *sync.WaitGroup) {
wg.Add(1)
m++
go func() {
wg.Done()
}()
}
// go test -bench=Benchmark -cpuprofile=cprof
func TestTraditional(t *testing.T) {
var wg sync.WaitGroup
for i := 0; i < 100000; i++ {
traditionalLogic(&wg)
}
wg.Wait()
println("final m:\n", m)
}
Scheduler 并不是单线程执行存在并发问题,执行结果为 99109 与 10000不符合
=== RUN TestBenchmark
final k:
99096
--- PASS: TestBenchmark (0.17s)
=== RUN TestTraditional
final m:
100000
--- PASS: TestTraditional (0.02s)
PASS
你都理解错了它的单线程同步的含义啊。它的意思是同一个调度中的所有任务,每个任务中fc.Yield前的代码和fc.Yield后的代码都是永远同时只有一个在执行啊,不包括fc.Yield(func)里面的func啊,那个func本来就是异步的其他地方去的啊。具体参考nodejs的async await,和lua的协程的概念啊。你在fc.Yield(func)里面的func里面计算个锤子啊