为了账号安全,请及时绑定邮箱和手机立即绑定

在戈鲁丁人之间同时划分任务

在戈鲁丁人之间同时划分任务

Go
饮歌长啸 2022-08-24 17:20:53
此代码的作用该代码从 Postgresql 数据库获取数据。从所有数据中,只有两个字段(会话和文本)被添加到 。Task Struct我的数据库中只有2个(每个)提到的数据,这意味着在做a时会返回我作为输出。len(task)2现在从这里开始,问题是什么:我制作了一个长度等于任务结构的长度(在本例中为 2)。buffered channel ch我指定允许的最大工作线程(线程)数,此处为 20。下面的代码所做的是,当我将任务发送到通道时,发送(此处为2)中的所有元素,并且任务结构中的示例代码将打印所有元素两次(=任务结构的长度)。示例显示在末尾。Task struct我需要什么才能让这个程序做什么例如,通道中有 100 个数据。我想将这100个数据分成20个Goroutines,每个Goroutines将处理5个数据(我不知道这是否可能,如果这无效,请提供其他解决方案)。len(task) = 100因此,100个数据将提供给20个工人,他们将每人接收5个数据并与他们一起运行任务,最后通道将关闭,仅此而已。当数据库变大并且当前也变大时,这将很有帮助。哪个会更好 20 个 Worker 分别执行任务,或者使 Worker 的数量等于通道中的数据数量?var wg sync.WaitGrouptype Task struct {    FetchedSession string    FetchedText    string}func FetchAllData() {    var task []Task    //Fetch Session from DB    var sess []database.UserSession    database.DB.Find(&sess)    //Fetch CommentText from DB    var cmt []database.CommentReq    database.DB.Find(&cmt)    if len(sess) == len(cmt) {        for i := range sess {            task = append(task, Task{FetchedSession: sess[i].Session, FetchedText: cmt[i].CommentText})        }    }    //making the Task Channel    ch := make(chan []Task, len(task))    MAX_WORKERS := 20    wg.Add(MAX_WORKERS)    for i := 0; i < MAX_WORKERS; i++ {        go func() {            for {                t, ok := <-ch                if !ok {                    wg.Done()                    return                }                DoTasks(t)            }        }()    }    for i := 0; i < len(task); i++ {        ch <- task    }    close(ch)    wg.Wait()}//Since Total number of data in Database is 2 (rows)//Currently this function takes all data from the channel and runs Twicefunc DoTasks(t []Task) {    //Total tasks (data) = 100    //If Max Workers = 20, then this function will run 5 times    //Each Goroutine will get 4 tasks from the channel    // Get the FetchedSession and FetchedTask and do tasks    fmt.Println(t) // This prints all data twice    //Finish one task and continue with the second}
查看完整描述

1 回答

?
慕哥9229398

TA贡献1877条经验 获得超6个赞

更改任务通道类型。

ch := make(chan Task, len(task))

这意味着在通道上传递的每个值都表示单个任务。


简化渠道迭代

    for i := 0; i < MAX_WORKERS; i++ {

        go func() {

            defer wg.Done()

            for t := range ch {

                DoTask(t)

            }

        }()

    }

wg.Done()现在将在工作线程退出时运行。 将在通道关闭并消耗所有任务后停止。range ch


更改“Do”功能以匹配

func DoTask(t Task) {

关于如何选择工作人员数量:


为函数运行一些基准测试,并尝试更改(或将其作为参数传递)。最佳值将取决于任务以及运行函数时的可用资源,这意味着今天机器上的最佳值可能不是其他任何机器上的最佳值,也不是明天机器上的最佳值。基准测试应该可以帮助您找到一个很好的近似范围来放置值。FetchAllDataMAX_WORKERS


查看完整回答
反对 回复 2022-08-24
  • 1 回答
  • 0 关注
  • 141 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号