go - 在嵌入式结构之间传递数据的最惯用的方法是什么?

标签 go design-patterns

我有两个结构

//Pseudo code
type task struct {}
type tasks struct []{
     t task 
}

我要运行一个任务,然后将其传递给任务:例如,在task1task2完成之后,通知tasks,然后运行task3。因此,这个task.finished()必须通知tasks.tasks必须确保task1task2均已完成,然后才能触发task3。
 //Pseudo code    
 task1.start() and task2.start() at the same time

 if  task1.finished() && task2.finished():
     task3.run()

在嵌入式结构之间传递数据的最惯用的方法是什么?

我知道应该在tasks中进行这种逻辑处理,但是task1task2如何告诉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()
}

Go PlayGround

实际上,您可以继续链接工作,

然后运行pendingTasks.OnComplete(someMoreTasks),一旦完成将运行mainTasks,一旦完成将运行PendingTasks

其他种类的复杂关系也是可能的。

关于go - 在嵌入式结构之间传递数据的最惯用的方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60257217/

相关文章:

mongodb - go mongo 驱动程序更新无法将对象数组设置为 null

json - 在 Go 中解码 json 时,我可以访问 "extra"字段吗?

c++ - CRTP 模式还在数据结构中存储非同质类型

objective-c - 将委托(delegate)移至他们自己的类(class)?

java - 多态性能做什么而继承不能?

go - 如何返回结构的实例,惯用的方式

session - 在 Gorilla session 中使用自定义类型

c# - 在 C# 中以函数式方式处理数据库事务

c++ - 交互类 - 组织代码

go - runtime._ExternalCode Cpu 使用率过高,高达 80%