2016-05-04 8 views
-2

私の理解から:チャネルがいっぱいになると、GOのバッファードチャネルはFIFOになりません。
私のアプリケーションでこの動作が必要です(FIFO動作)。
どうすればこのような動作を実現できますか?そのためのオープンソースはありますか?事前に
おかげゴランFIFOバッファーチャネル

EDIT:
私は、バッファチャンネルがいっぱいで、複数の送信者が
を遮断しているときにアイテムを追加しようとしたときにことを意味:
一部の人は、そう私はより明確にしましょう質問を嫌っそれらがリリースされる順序でチャンネル
はFIFOではありません。また、このディスカッションを読むことができます:https://github.com/golang/go/issues/11506

私はその動作を実装するサードパーティのライブラリを探していました。
ご迷惑をおかけして申し訳ありません。

+0

これはGoでチャンネルが動作する方法です。あなたはチャンネルを使用してこれを達成することができます...申し訳ありませんが、絶対にひどい質問です。 – evanmcdonnal

+1

@evanmcdonnalフルチャネルでブロックされた送信者の実行順序は不定です。このFIFOを作る方法を尋ねるのはひどいことではありません。この仕様には、チャンネルを使用してこれを達成できるとは言いません...この問題の問題は、ソフトウェアパッケージをお勧めすることです。 –

+1

@KarrotKakeいいえアイテムが最初に最初に出された順番でチャンネルから読み込まれるということはかなり明白だと思います。 – evanmcdonnal

答えて

6

Goのバッファチャネルは常にFIFOです。仕様は明らかに次のように述べています。

チャネルが先入れ先出しキューとして機能します。

チャネルから出力される値がFIFOでない場合、これはチャネル実装のバグです。

次のコードは、常に印刷する必要が1、2、この正しい順序で3、4:

package main 

import (
    "fmt" 
    "time" 
) 

func main() { 
    ch := make(chan int, 3) 
    ch <- 1 
    ch <- 2 
    ch <- 3 

    go func() { 
     ch <- 4 
    }() 

    time.Sleep(time.Second) 

    for i := 0; i < 4; i++ { 
     fmt.Println(<-ch) 
    } 
} 

Playground link

値が最初に送信されないguaruanteeがないことに注意してくださいが複数の同時送信者です。複数の待機中の送信者がいて、誰かがチャネルバッファから1つの要素を削除した場合(またはバッファされていないチャネルの場合はチャネルから受信しようとします)、ランタイムはランダムに送信ゴルーチンの1つを選択します。

例:

package main 

import (
    "fmt" 
    "time" 
) 

func main() { 
    ch := make(chan int, 2) 
    ch <- 1 

    go func() { 
     ch <- 2 
    }() 

    go func() { 
     ch <- 3 
    }() 

    time.Sleep(time.Second) 

    for i := 0; i < 3; i++ { 
     fmt.Println(<-ch) 
    } 
} 

Playground link

あなたはこのコードを複数回実行した場合、あなたは出力は時々2、3、1、2、3または1のどちらかになりますことがわかります(この出力がキャッシュされるので、プレイグラウンドでは動作しません)

+0

複数の送信者がいる場合、最初にブロックされた送信者が最初に解放されるという保証はありません。それは私が「チャンネル内のバッファされたチャンネルは、チャンネルがいっぱいになるとFIFOではない」と言ったときの意味です。とにかく、Fifoの送信者をブロックした実装を探しています。 – user3142398

+1

@ user3142398これを行うには、それを自分で実装する必要があります。私はこれを行うパッケージについて知らない。あなたはおそらく、キューとコンディション変数をインクリメントしたカウンタで使用することができますが、それはあまり効率的ではありません。 – nussjustin