Pythonとの類似点と相違点Golangコルーチン

文化的背景

ここでは、以下の記事の内容を理解するために、一般的な知識のいくつかの簡単な説明を与えます。

プロセス定義:

プロセスは、エンティティがすでにプログラムを実行しているコンピュータです。命令プログラム自体が本当に記述形式のデータとそれらの組織のインスタンスを実行している、プロセスは、プロセスです。

スレッドの定義:

オペレーティング・システムは、最小単位操作をスケジュールすることができます。これは、プロセスの単位プロセスの実際の動作が含まれます。

関係のプロセスとスレッド:

スレッドは、プロセスシーケンスの単一の制御フローを参照して、プロセスは、並行して、各スレッドは、異なるタスクを実行するために、複数のスレッドによって複雑にすることができます。
最小スケジューリング部CPUスレッドは、プロセスではないので、単一のマルチスレッド・プロセスは、マルチコアCPUを使用することができます。

コルーチンの定義:

スレッドのスケジューリングにコルーチンを実装することにより、カーネルレベルのコンテキストの切り替えにパフォーマンスの低下を避けるためには、このようにIOの上でスレッドのパフォーマンスのボトルネックを壊し、引き起こしました。

プロセスとスレッドの関係研究所

コルーチンは、消費コンテキストのカーネルレベルを回避するために、言語レベルでのスレッドのスケジューリングを達成することです。

pythonコルーチン

Pythonコマンドからコルーチンの収率。収量は、2つの機能があります。

  • 出力にフィードバック次の()呼び出し元に値をアイテムを得ます。
  • 譲歩は、発信者が動作し続けるようにあなたが別の値が必要になるまで、[次へ]を呼び出して、発電機を停止するようにするには()。
import asyncio


async def compute(x, y):
    print("Compute %s + %s ..." % (x, y))
    await asyncio.sleep(x + y)
    return x + y


async def print_sum(x, y):
    result = await compute(x, y)
    print("%s + %s = %s" % (x, y, result))


loop = asyncio.get_event_loop()
tasks = [print_sum(1, 2), print_sum(3, 4)]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()

コルーチンは、スレッドのためにスケジュールされ、収率同様遅延評価は、Python3.5の正式な導入に、協調マルチタスクを実装するプロセス制御ツールとして見ることができるasync/awaitコルーチンは、公式にはサポートし、言語レベルで最適化された製造、式収率が大幅に簡略化され、前に書かれました。
プリエンプティブカーネルスレッドは、このように各スレッドが実行する機会を持っていることを確実にすること、予定されています。
そして、coroutine実行時の言語があることで、同じスレッドで実行するEventLoop(イベントループ)をスケジュールします。
ほとんどの言語で、Pythonで、コルーチンはコルーチンを実行するための機会を放棄するためのイニシアチブをとる必要があることを意味非プリエンプティブスケジューリング、であるため、他のコルーチンは実行する機会を持っています。
キーワードが待っているんみましょう。言い換えれば、コルーチンがブロックされている場合、CPUを維持し続け、その後、全体のスレッドが任意の同時実行せず、立ち往生。

要するに、任意の時間はわずか1つのコルーチンが実行されています。

PS:サーバーとして、イベントループは、IO多重化は、多重化機能により、クライアントからのすべての要求は、IOを処理するためのコアがあり、クライアントとして、コアイベントループ遅延はFutureオブジェクトの実行を利用することで、そして、次のプロセスが完了した後にコールバック関数の戻りを起動すると、サーバーの処理を待っていることは続けて、ハング、コルーチンを刺激するために送信機能を使用します

コルーチン行きます

自然言語サポートのレベルを移動し、Pythonが類似したキーワードに基づいていますが、移動中にコルーチンは、言語は最も重要な特性で行く指示する場合があり、このキーワードを使用して行きます。
外出先コルーチン間の通信は、チャンネルキーを使って移動します。

ゴーは、2つの同時のフォームを実装します。

  • マルチスレッドの共有メモリ。場合JavaやC ++などのロックを介してアクセスされるマルチスレッドで共有データ(例えば配列、マップ、または構造またはオブジェクト)。
  • 言語固有の推奨するだけでなく、移動中に行く:CSPは、同時実行モデル(一連の処理を伝えます)。

実施CSP移動の同時実行モデル:M、P、G:[ HTTPS://www.cnblogs.com/sunsk ... ]

package main

import (
    "fmt"
)

//Go 协程(goroutines)和协程(coroutines)
//Go 协程意味着并行(或者可以以并行的方式部署),协程一般来说不是这样的
//Go 协程通过通道来通信;协程通过让出和恢复操作来通信

// 进程退出时不会等待并发任务结束,可用通道(channel)阻塞,然后发出退出信号
func main() {
    jobs := make(chan int)
    done := make(chan bool) // 结束标志

    go func() {
        for {
            j, more := <-jobs //  利用more这个值来判断通道是否关闭,如果关闭了,那么more的值为false,并且通知给通道done
            fmt.Println("----->:", j, more)
            if more {
                fmt.Println("received job", j)
            } else {
                fmt.Println("end received jobs")
                done <- true
                return
            }
        }
    }()

    go func() {
        for j := 1; j <= 3; j++ {
            jobs <- j
            fmt.Println("sent job", j)
        }
        close(jobs) // 写完最后的数据,紧接着就close掉
        fmt.Println("close(jobs)")
    }()

    fmt.Println("sent all jobs")
    <-done // 让main等待全部协程完成工作
}

関数呼び出しの前にキーワードを使用することによりgo、我々は、この関数を作ることができgoroutine、実行ファッション。goroutineこれは、安価な資源コルーチンスレッドよりも軽量です。
各機能は、ユニットのコルーチンに実行行くことができますキーワードを使用して実行されるように、システムの実装により、これらの関数の複数のスレッドを派遣する言語を移動します。
コルーチンがブロックされた場合、スケジューラは自動的に並列化を待たずにプログラムの動作を可能にする、追加のスレッドを実行するために他のコルーチンを手配します。
そして、スケジューリングオーバーヘッドは、私たちはの多くを作成することができます毎秒劣らず万人の1倍以上のCPUスケジューリングのサイズ、非常に小さいgoroutineので、それは非常に並行プログラムを書くのは簡単だ、私たちは目的を達成したいです。----ブック

四つの状態コルーチン

  • 保留中
  • ランニング
  • 完了
  • Cacelled

そして、システムスレッド間の関係をマッピングします

事のスレッドは、コルーチン自然が行くか、システム呼び出し、Pythonでコルーチンはイベントループモデルの実装である、コルーチン呼び出しもののそうではなく。
コルーチンでPythonは厳密に1:Nの関係、これは、コルーチンの複数に対応するスレッドです。非同期I / Oが、しかし効果的マルチコア(GIL)を使用することができません。
GoはMである:Nの関係つまり、NのコルーチンがMのスレッドに割り当てられてマッピングされ、これには2つの利点をもたらします:

  • 複数のスレッドがゴルーチンを使用してCPU集約型のアプリケーションが加速してしまいます、別のコアに割り当てることができます。
  • 操作をブロックする少量でも、それが唯一のワーカースレッドをブロックします、プログラム全体が目詰まりしません。

PS:めったに言及していないスレッドやプロセスを行く、それが原因で上記の理由です。

PythonとGolangのコルーチンの比較:

  • Pythonはあるasyncあなたが使用して開始すると、ノンプリエンプティブasync機能を、そしてあなたの全体のプログラムがなければなりませんasyncそれ以外の場合は、常にあなたは、ディスパッチャは、他のコルーチンをスケジューリングしてみましょうするためのイニシアチブをとることはできません実現しなかった場所(ライブラリの非同期性に閉塞の場合を阻止され、 a)は、それがあるasync伝染。
  • その上で要求、redis.py、オープン関数および:全体の非同期プログラミング環境問題Pythonは、標準ライブラリやサードパーティのライブラリの多様前のような、閉塞機能を使用しないでください。だから、Python3.5プロセスを使用することは困難ではありませんが、良くない生態環境の後に協会に参加する最大の問題、歴史的な負担は再び上演、一緒に技術をベースに、マルチコア動的言語間のタスクスケジューリングでは困難である必要があり、心からのマルチコアパフォーマンスの向上を使用して、python4.0が最適化されたか、GILロックを放棄することができることを願っています。
  • goroutineゴーはそうほぼすべてのライブラリは全てを書き換える必要がありPythonライブラリの問題を回避、直接使用されている、生来の特性です。
  • goroutine明示的な使用を必要としないawait放棄コントロールを、それがスケジュールするタイムスライスに厳密に従って行くことはありませんgoroutineが、スケジューリングが可能な場合、障害物が挿入されます。goroutineスケジューリングは、半プリエンプティブとして見ることができます。

PS:Pythonの非同期ライブラリリスト[ HTTPS://github.com/timofurrer ... ]


メモリを共有することで通信しない;代わりに、通信することにより、共有メモリ(通信を介して、逆に通信しない共有メモリ・アプローチが共有されるメモリ) - CSPの並行モデル。


拡張と要約

golangのアーラン及びCSP(通信一連の処理)に基づいてモード(コルーチンでPythonがイベントループモデルである)
が、Erlangのプロセスベースのメッセージングは、ゴルーチンと通信チャネルをベースに行きます。
ロックの影響とプロセス大/スレッドのオーバーヘッドの問題を回避するために、Pythonとメッセージスケジューリングシステムモデルを導入した移動します。
コルーチンスレッドは、システムがプリエンプティブスケジューリングを実行する必要はありませんが、言語レベルのスレッドのスケジューリングを達成するために、基本的にユーザー状態です。
ロックは、多くのスーパーシステムを持っているため、共有メモリは、もはや使用コルーチン/データが、/ロックへの共有メモリ通信を使用しているため、
共有変数などシステム全体が非常に煩雑になると作るが、メッセージを通じてます交換機構は、各セルは、同時に、別個の実体となるようにすることができる
セル間で共有されていない独自の変数、入力メッセージのための唯一の出力部と。
開発者は、他のプログラムにメモリ/データ共有修飾同様の影響を考慮する必要なく、同時入出力部への影響、約のみ関心を必要とします。

おすすめ

転載: www.cnblogs.com/huang-yc/p/11229134.html