猿问

Go 相当于 GCD 串行调度队列

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

到目前为止,我只找到了一个函数通道的解决方案。

work := make(chan func())

我会有一个从这个频道接收的函数并调用接收到的函数。这些功能必须按 FIFO 顺序执行。

在 Go 中有没有更好的方法或结构来做到这一点?

这应该没有区别,但我希望为此将 SQL 查询排队以在 FIFO 中运行。


www说
浏览 163回答 2
2回答

烙印99

它很接近但不完全。我最终在此处提供了 Go 中的串行调度队列实现。它基本上是一个 go 例程,它阻塞 achannel类型func()并运行按顺序传递的函数。执行://Package serialqueue provides a serial queue for functions.&nbsp;//Queue items are processed in First In First Out (FIFO) order.&nbsp;package serialqueue//New returns a new serial queue.//Enqueue items like queueObj <- func() {doWork(data)}func New() chan func() {&nbsp; &nbsp; //create channel of type function&nbsp; &nbsp; var queue = make(chan func())&nbsp; &nbsp; //spawn go routine to read and run functions in the channel&nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; for true {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nextFunction := <-queue&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nextFunction()&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }()&nbsp; &nbsp; return queue}用法:(演示以正确顺序写入字符串)//Package serialqueue provides provides tests for github.com/ansonl/serialqueue.&nbsp;package serialqueue_testimport (&nbsp; &nbsp; "testing"&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "sync"&nbsp; &nbsp; "github.com/ansonl/serialqueue"&nbsp; &nbsp; )func TestQueue(t *testing.T) {&nbsp; &nbsp; //Create new serial queue&nbsp; &nbsp; queue := serialqueue.New()&nbsp; &nbsp; //Number of times to loop&nbsp; &nbsp; var loops = 100&nbsp; &nbsp; //Queue output will be added here&nbsp; &nbsp; var queueOutput string&nbsp; &nbsp; //WaitGroup for determining when queue output is finished&nbsp; &nbsp; var wg sync.WaitGroup&nbsp; &nbsp; //Create function to place in queue&nbsp; &nbsp; var printTest = func(i int) {&nbsp; &nbsp; &nbsp; &nbsp; queueOutput = fmt.Sprintf("%v%v",queueOutput, i)&nbsp; &nbsp; &nbsp; &nbsp; wg.Done()&nbsp; &nbsp; }&nbsp; &nbsp; //Add functions to queue&nbsp; &nbsp; var i int;&nbsp; &nbsp; for i=0;i<loops;i++ {&nbsp; &nbsp; &nbsp; &nbsp; wg.Add(1)&nbsp; &nbsp; &nbsp; &nbsp; t:=i&nbsp; &nbsp; &nbsp; &nbsp; queue <- func() {printTest(t)}&nbsp; &nbsp; }&nbsp; &nbsp; //Generate correct output&nbsp; &nbsp; var correctOutput string&nbsp; &nbsp; for i=0;i<loops;i++ {&nbsp; &nbsp; &nbsp; &nbsp; correctOutput = fmt.Sprintf("%v%v", correctOutput, i)&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; }&nbsp; &nbsp; //Wait until all functions in queue are done&nbsp; &nbsp; wg.Wait()&nbsp; &nbsp; //Compare queue output with correct output&nbsp; &nbsp; if queueOutput != correctOutput {&nbsp; &nbsp; &nbsp; &nbsp; t.Errorf("Serial Queue produced %v, want %v", queueOutput, correctOutput);&nbsp; &nbsp; }}希望这可以帮助有同样问题的人!

紫衣仙女

这样的事情应该可以工作,但是我不熟悉 GCD 的工作原理,所以我可能会离开。func main() {&nbsp; &nbsp; q := NewQueue(10) // the size is mainly so it wouldn't block, you can play with that to your liking.&nbsp; &nbsp; var wg sync.WaitGroup&nbsp; &nbsp; for i := 0; i < 10; i++ {&nbsp; &nbsp; &nbsp; &nbsp; wg.Add(1)&nbsp; &nbsp; &nbsp; &nbsp; i := i&nbsp; &nbsp; &nbsp; &nbsp; q <- func() { log.Println("i =", i); wg.Done() }&nbsp; &nbsp; }&nbsp; &nbsp; wg.Wait()&nbsp; &nbsp; close(q)}func NewQueue(size int) (q chan func()) {&nbsp; &nbsp; q = make(chan func(), size)&nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; for fn := range q {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fn()&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }()&nbsp; &nbsp; return}
随时随地看视频慕课网APP

相关分类

Go
我要回答