2016-01-21 2 views
0

Есть ли эквивалент серийной очереди отправки GCD от Apple?Go эквивалент очереди последовательной отправки GCD

До сих пор я нашел решение, которое является каналом функций.

work := make(chan func()) 

У меня была бы функция приема от этого канала и вызова полученных функций. Функции должны выполняться в порядке FIFO.

Есть ли лучший способ или структура для этого в Go?

Это не должно иметь значения, но я ищу очереди запросов SQL для запуска в FIFO для этого.

ответ

1

@OneOfOne, он был близок, но не совсем.

В итоге я создал реализацию очереди очередей в Go Go here.

Это обычная процедура, которая блокирует на 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); 
    } 
} 

Надеется, что это помогает кто-то с той же проблемой!

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

Смежные вопросы