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のどちらかになりますことがわかります(この出力がキャッシュされるので、プレイグラウンドでは動作しません)
これはGoでチャンネルが動作する方法です。あなたはチャンネルを使用してこれを達成することができます...申し訳ありませんが、絶対にひどい質問です。 – evanmcdonnal
@evanmcdonnalフルチャネルでブロックされた送信者の実行順序は不定です。このFIFOを作る方法を尋ねるのはひどいことではありません。この仕様には、チャンネルを使用してこれを達成できるとは言いません...この問題の問題は、ソフトウェアパッケージをお勧めすることです。 –
@KarrotKakeいいえアイテムが最初に最初に出された順番でチャンネルから読み込まれるということはかなり明白だと思います。 – evanmcdonnal