我有两个结构
//Pseudo code
type task struct {}
type tasks struct []{
t task
}
我想运行一个任务,并在它完成后将信息传递给任务:例如,在task1
和task2
完成后,通知tasks
,然后运行task3
。因此,这一个task.finished()
必须通知tasks.
,tasks
必须确保task1
和task2
都已完成,然后触发task3。
//Pseudo code
task1.start() and task2.start() at the same time
if task1.finished() && task2.finished():
task3.run()
在嵌入式结构之间传递数据的最惯用方法是什么?
我知道这样的逻辑应该在tasks
进行,但是task1
和task2
如何告诉他们tasks
完成?
我是否应该引入一个名为"taskManager"的新结构来存储交换所需的信息?
type tasks []*task
type task struct {
Data int
onComplete chan struct{}
}
var wg sync.WaitGroup
// each task will in one goroutine
// pointer receiver
func (t *task) Run() {
defer wg.Done()
sleepTime := time.Second * time.Duration(t.Data)
fmt.Println("Task:", t.Data, "sleeping for", sleepTime)
time.Sleep(sleepTime)
fmt.Println("Task:", t.Data, "done")
// Once work is done, Inform, if we have to
if t.onComplete != nil {
t.onComplete <- struct{}{}
}
}
// Run given tasks
func Run(ts tasks) {
wg.Add(len(ts))
for _, t := range ts {
// run each task in seperate goroutines
go t.Run()
}
}
func (ts tasks) OnComplete(pending tasks) {
tempChan := make(chan struct{})
// all tasks should inform to `tempChan`,
// once done
for _, t := range ts {
t.onComplete = tempChan
}
tasksNum := len(ts)
wg.Add(1)
go func() {
// once we receive enough signals
// i.e., once all `ts` tasks are done run pending tasks
for range tempChan {
tasksNum--
if tasksNum == 0 {
Run(pending)
close(tempChan)
}
}
wg.Done()
}()
}
func main() {
// define tasks
mainTasks := tasks{
{Data: 1},
{Data: 2},
}
// tasks which need to run once certain tasks were done
pendingTasks := tasks{
{Data: 3},
}
// Inform to run pending tasks once mainTasks are done
mainTasks.OnComplete(pendingTasks)
// start runing your main tasks
Run(mainTasks)
wg.Wait()
}
去游乐场
事实上,你可以继续链接工作,pendingTasks.OnComplete(someMoreTasks)
然后运行mainTasks
,一旦完成将运行PendingTasks
,一旦完成将运行someMoreTasks
。
其他类型的复杂关系也是可能的。