どのようにGolangのchanelを使ってnodejsのstreamのように糸を滑りますか?
2576 ワード
Golangの特徴を他の人に話してもらえば、まずgoroutineとは限らないと思いますが、きっとchanelです.
Channelの存在のため、Goroutineの威力をプラスする利器です.
一言でチャンネルの役割を説明すれば、私は言います.
Chanelはパイプです.データが流れます.
++では、これをどのように理解してデータを流れさせますか?+
もしあなたが100回の要求を必要とするなら、2つの比較的に時間がかかる操作をして、重み付け結果を統計して、できるだけ同時に性能を向上させる必要があります.サンプルコードは以下の通りです.
一度書いたらいいかもしれませんが、多くのところでこのように書くと、本当に頭が大きいです.
繰り返しコードは悪の源であり、Don't repeat yourselfは優れたエンジニアになるための第一歩である.
そして、chanelxという倉庫が誕生しました!
このライブラリを使って、上記と同じ機能を実現します.コードはこのようにしています.
Pipe->Harvestの組み合わせの他に、Pipe->Race、Pipe->Drain、Pipe->Canceなどの操作の組み合わせが実現できます.
これらの複雑な例は、すべてstream_を参照することができます.test.goファイルの中のユニットテストが実現したら、コードを一つ一つ貼り付けなくなりますよ.
このストリアはどうやって実現されますか?コアはNewChanelStreamとPipeの二つの関数にあります.
まず、NewChanelStreamでinput Chanを新たに作成してseedFunに伝えます.その後、データはseedChanを通じてdata Chanelに伝えられます.
そして、Pipeを呼び出すと、Pipe関数は自分でseedFncを作成して、前のチャンネルStreamのdata Chanelからdata PipeChanelに伝えます.このPipeの中のseedFunはまたNewChanelStreamに入ってきます.新しいチャンネルStreamオブジェクトが生まれます.この時、新しいチャンネルStreamの中でinputChanつまりPipeのdata Pipe Chanelで、全体のデータストリームはこのように連結されました.過程は以下の通りです.
inputChan->data Chanel->inputChann->data Chanel....
ソースコードを分析して、ChanelStreamを使った例と直接Chanelを使った例を見てみると、2つのdata Chanelがそれぞれ対応しているのはmultileChanとminusChanで、多く出ている2つのinputChanは、このライブラリを使った余分な出費です.
オリジナルは簡単ではないです.あなたのサポートは私にとって最大の励ましです.チャンネルxにスターを注文してください.
まだまだ続きますが、チャンネルxには、さまざまな常用シーンが続々と追加されますので、ご期待ください.
Channelの存在のため、Goroutineの威力をプラスする利器です.
一言でチャンネルの役割を説明すれば、私は言います.
Chanelはパイプです.データが流れます.
++では、これをどのように理解してデータを流れさせますか?+
もしあなたが100回の要求を必要とするなら、2つの比較的に時間がかかる操作をして、重み付け結果を統計して、できるだけ同時に性能を向上させる必要があります.サンプルコードは以下の通りです.
var multipleChan = make(chan int, 4)
var minusChan = make(chan int, 4)
var harvestChan = make(chan int, 4)
defer close(multipleChan)
defer close(minusChan)
defer close(harvestChan)
go func() {
for i:=1;i<=100;i++{
multipleChan
このコードは簡単だと笑わないでください.エラー処理の状況を考えると、まだ複雑です.例えば、ある環節は間違いがあったら無視してもいいです.ある環節はすべての操作を終了することに出会うのです.加えて、最初の満足条件の戻り値のみに関心を持つ場合があり、タイムアウト処理が必要です.一度書いたらいいかもしれませんが、多くのところでこのように書くと、本当に頭が大きいです.
繰り返しコードは悪の源であり、Don't repeat yourselfは優れたエンジニアになるための第一歩である.
そして、chanelxという倉庫が誕生しました!
このライブラリを使って、上記と同じ機能を実現します.コードはこのようにしています.
var sum = 0
NewChannelStream(func(seedChan chan
チェーンスタイルが好きですので、このように書いてもいいです.コードを書くのがポイントですが、糸が滑るので、nodejs stream流の快感があります.Pipe->Harvestの組み合わせの他に、Pipe->Race、Pipe->Drain、Pipe->Canceなどの操作の組み合わせが実現できます.
これらの複雑な例は、すべてstream_を参照することができます.test.goファイルの中のユニットテストが実現したら、コードを一つ一つ貼り付けなくなりますよ.
このストリアはどうやって実現されますか?コアはNewChanelStreamとPipeの二つの関数にあります.
func NewChannelStream(seedFunc SeedFunc, optionFuncs ...OptionFunc) *ChannelStream {
cs := &ChannelStream{
workers: runtime.NumCPU(),
optionFuncs: optionFuncs,
}
for _, of := range optionFuncs {
of(cs)
}
if cs.quitChan == nil {
cs.quitChan = make(chan struct{})
}
cs.dataChannel = make(chan Item, cs.workers)
go func() {
inputChan := make(chan Item)
go seedFunc(inputChan, cs.quitChan)
loop:
for {
select {
case
コードは多く見ています.初期化コード、エラー処理と終了処理コードをカットします.コアはやはりチャンネルを通じたデータの流れです.まず、NewChanelStreamでinput Chanを新たに作成してseedFunに伝えます.その後、データはseedChanを通じてdata Chanelに伝えられます.
そして、Pipeを呼び出すと、Pipe関数は自分でseedFncを作成して、前のチャンネルStreamのdata Chanelからdata PipeChanelに伝えます.このPipeの中のseedFunはまたNewChanelStreamに入ってきます.新しいチャンネルStreamオブジェクトが生まれます.この時、新しいチャンネルStreamの中でinputChanつまりPipeのdata Pipe Chanelで、全体のデータストリームはこのように連結されました.過程は以下の通りです.
inputChan->data Chanel->inputChann->data Chanel....
ソースコードを分析して、ChanelStreamを使った例と直接Chanelを使った例を見てみると、2つのdata Chanelがそれぞれ対応しているのはmultileChanとminusChanで、多く出ている2つのinputChanは、このライブラリを使った余分な出費です.
オリジナルは簡単ではないです.あなたのサポートは私にとって最大の励ましです.チャンネルxにスターを注文してください.
まだまだ続きますが、チャンネルxには、さまざまな常用シーンが続々と追加されますので、ご期待ください.