相当于GCD串行调度队列

时间:2016-01-21 14:51:20

标签: sql go queue grand-central-dispatch

是否有相当于Apple的GCD串行调度队列?

到目前为止,我只找到了一个功能渠道的解决方案。

work := make(chan func()) 

我将从该频道接收函数并调用接收的函数。必须按FIFO顺序执行这些功能。

Go中是否有更好的方法或结构?

这不应该有所作为,但我希望将SQL查询排队以在FIFO中运行。

2 个答案:

答案 0 :(得分:1)

@OneOfOne,它很接近但不完全。

我最终在Go中提供了一个Serial Dispatch Queue实现here

它基本上是一个go例程,它阻塞channel类型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);
    }
}

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

答案 1 :(得分:0)

这样的事情应该有用,但是我不熟悉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
}

playground