2015-07-25 2 views
0

Мне нужна помощь, чтобы понять, почему следующий код не работает. Я строю конвейер и пытаюсь выполнить шаг, который синхронизирует значения из двух исходных каналов. Мой код источника/производителя выглядит примерно так (в моем реальном коде я читаю текст из файла). Источники сортируются, но значения не гарантируются в обоих источниках.Как синхронизировать goroutines в конвейере

func Source() <-chan int{ 
    out := make(chan int, 5) 

    go func() { 
     defer reader.Close() 

     out <- 1 
     out <- 2 
     out <- 3 
     out <- 4 
     out <- 5 
     out <- 7 

     close(out) 
    }() 

    return out 
} 

и код синхронизации выглядит следующим образом:

func Sync(a, b <-chan int) <-chan int { 
    out := make(chan int) 

    go func() { 
     av, ak:= <-a 
     bv, bk:= <-b 

     for ak || bk { 

      if !ak || av < bv { 
       out <- bv 

       bv, bk = <-b 
       continue 
      } 

      if !bk|| bv > av { 
       out <- av 

       av, ak = <-a 
       continue 
      } 

      out <- av 

      av, ak = <-a 
      bv, bk = <-b 
     } 

     close(out) 
    }() 

    return out 
} 

и моя программа выглядит следующим образом:

func main() { 
    os := Source() 
    ns := Source() 

    for val := range Sync(ns, os) { 
     fmt.Printf("[SYNCED] %v \n", val) 
    } 
} 

Ожидаемое поведение является то, что мои оба источника буфера значения в канале и моя синхронизация сначала считывает значение из первого источника. Затем со второго. Сравните их и, если они равны, продолжит следующий в обоих каналах. Если они отличаются, мы отправим значение, которое стоит, и заменим его новым, и повторим аналогичное сравнение.

Что происходит, так это то, что код синхронизации выполняется несколько раз для значений, и я получаю такие вещи, как [SYNCED] 1 несколько раз. Зачем?

Пожалуйста, помогите мне исправить это!

+0

Не уверен, что образец содержит достаточно, чтобы воспроизвести проблему: http://play.golang.org/p/jG_rDP7wpb – twotwotwo

+0

Это похоже на 'if! Ak || av av' может быть логической ошибкой. Из остальных этих утверждений видно, что они должны отражать друг друга, но 'av av' - это разные способы указать то же самое условие, а не условия зеркального отображения. – twotwotwo

+0

(Например, если цель была «выводима в зависимости от того, какой вход больше», сравнение в этой секунде «if» должно быть «bv twotwotwo

ответ

2

Что касается http://play.golang.org/p/uhd3EWrwEo и http://play.golang.org/p/Dqq7-cPaFq -

На самом деле, код Интс проваливается с аналогичным теста, а также:

os := Source([]int{1, 2, 3}) 
ns := Source([]int{1, 3, 4}) 

ставит версию INTS в бесконечный цикл.

Это происходит потому, что когда !aok || avalue > bvalue проверяется, он не принимает во внимание, что если aok верно (некоторые элементы все еще находятся в a) и bok ложна (больше нет элементов в b), то avalue > "" всегда верно. Поэтому он пытается взять другой элемент из b (который пуст) и переходит в бесконечный цикл. Фиксированный код: http://play.golang.org/p/vYhuOZxRMl

+0

Спасибо! Я очень ценю вашу помощь! – mckn

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