1 回答

TA貢獻1836條經(jīng)驗 獲得超4個贊
你是對的,這WaitGroup可能就是你想要的。但是,您沒有正確使用它。首先,您需要在wg.Add(1)調(diào)用wg.Done(). 其次,調(diào)用wg.Wait()塊直到等待組中的所有 go routines 完成執(zhí)行,所以你不希望它并發(fā)執(zhí)行。
至于短路,確實沒有什么好辦法。我的建議是使用上下文。在這種情況下,您必須做的一件事是將上下文連接到您的調(diào)用中,nodeHasCycle如果您想要真正的短路行為。
修復你的代碼,我們有:
func (c *cycleDet) hasCycle() bool {
ctx, cancel := context.WithCancel(context.Background())
hasCycle := make(chan bool)
var wg sync.WaitGroup
adj := c.b // adjacency list representation of the unerlying graph
for node := range adj {
wg.Add(1)
go func(ctx context.Context, no nodeID, co chan<- bool, cancel context.CancelFunc) {
// Use wg to synchronize termination of read-only goroutines.
defer wg.Done()
select {
case <-ctx.Done():
return
default:
}
visited := make(map[nodeID]struct{})
// c.nodeHasCycle will use a recursive implementation of DFS to
// find out if the node no leads to a cycle.
if c.nodeHasCycle(ctx, no, visited) {
co <- true
cancel()
return
}
}(ctx, node, hasCycle, cancel)
}
// Observer goroutine to notify when wg is done waiting.
time.Sleep(100 * time.Millisecond)
wg.Wait()
defer cancel()
select {
case <-hasCycle:
fmt.Println("got a cycle")
return true
default:
fmt.Println("no cycle detected")
return false
}
}
通過這種方式設置,您可以確保對 go-routine 的所有調(diào)用都將運行,除非找到一個循環(huán),在這種情況下,不會調(diào)用其他 go-routes 并且,如果您添加邏輯以檢查是否取消nodeHasSycle,則您也可以停止對任何正在運行的調(diào)用的執(zhí)行。
- 1 回答
- 0 關注
- 125 瀏覽
添加回答
舉報