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

Go 相当于 GCD 串行调度队列

Go 相当于 GCD 串行调度队列

Go
www说 2021-12-07 14:55:30
是否有相当于 Apple 的 GCD 串行调度队列的 Go?到目前为止,我只找到了一个函数通道的解决方案。work := make(chan func())我会有一个从这个频道接收的函数并调用接收到的函数。这些功能必须按 FIFO 顺序执行。在 Go 中有没有更好的方法或结构来做到这一点?这应该没有区别,但我希望为此将 SQL 查询排队以在 FIFO 中运行。
查看完整描述

2 回答

?
烙印99

TA贡献1829条经验 获得超13个赞

它很接近但不完全。


我最终在此处提供了 Go 中的串行调度队列实现。


它基本上是一个 go 例程,它阻塞 achannel类型func()并运行按顺序传递的函数。


执行:


//Package serialqueue provides a serial queue for functions. 

//Queue items are processed in First In First Out (FIFO) order. 

package serialqueue


//New returns a new serial queue.

//Enqueue items like queueObj <- func() {doWork(data)}

func New() chan func() {

    //create channel of type function

    var queue = make(chan func())


    //spawn go routine to read and run functions in the channel

    go func() {

        for true {

            nextFunction := <-queue

            nextFunction()

        }

    }()


    return queue

}

用法:(演示以正确顺序写入字符串)


//Package serialqueue provides provides tests for github.com/ansonl/serialqueue. 

package serialqueue_test


import (

    "testing"

    "fmt"

    "sync"

    "github.com/ansonl/serialqueue"

    )


func TestQueue(t *testing.T) {

    //Create new serial queue

    queue := serialqueue.New()


    //Number of times to loop

    var loops = 100


    //Queue output will be added here

    var queueOutput string


    //WaitGroup for determining when queue output is finished

    var wg sync.WaitGroup


    //Create function to place in queue

    var printTest = func(i int) {

        queueOutput = fmt.Sprintf("%v%v",queueOutput, i)

        wg.Done()

    }


    //Add functions to queue

    var i int;

    for i=0;i<loops;i++ {

        wg.Add(1)

        t:=i

        queue <- func() {printTest(t)}

    }


    //Generate correct output

    var correctOutput string

    for i=0;i<loops;i++ {

        correctOutput = fmt.Sprintf("%v%v", correctOutput, i)       

    }


    //Wait until all functions in queue are done

    wg.Wait()


    //Compare queue output with correct output

    if queueOutput != correctOutput {

        t.Errorf("Serial Queue produced %v, want %v", queueOutput, correctOutput);

    }

}

希望这可以帮助有同样问题的人!


查看完整回答
反对 回复 2021-12-07
?
紫衣仙女

TA贡献1839条经验 获得超15个赞

这样的事情应该可以工作,但是我不熟悉 GCD 的工作原理,所以我可能会离开。


func main() {

    q := NewQueue(10) // the size is mainly so it wouldn't block, you can play with that to your liking.

    var wg sync.WaitGroup

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

        wg.Add(1)

        i := i

        q <- func() { log.Println("i =", i); wg.Done() }

    }

    wg.Wait()

    close(q)

}


func NewQueue(size int) (q chan func()) {

    q = make(chan func(), size)

    go func() {

        for fn := range q {

            fn()

        }

    }()

    return

}


查看完整回答
反对 回复 2021-12-07
  • 2 回答
  • 0 关注
  • 162 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信