猫型エンジニアのブログ

プログラム/ネットワーク系の技術関連をまとめたページです 

(翻訳)Greenlet vs Thread

 Greenletの勉強にあたって検索ででてきた、以下のGreenletおよびスレッドの比較に関するページ
python - Greenlet Vs. Threads - Stack Overflow
の一部分を意訳しました。和訳された技術書のように、典型的な非常に読みにくい日本語になってしまいました...。訳した私も内容を咀嚼できていません。

(以下意訳)
Greenletは並行性(concurrency)は提供しますが、並列性(parallelism)は提供しません。並行性では、コードの各部分が他の部分からは独立して実行されます。並列性は同一のコードを同時に実行することです。並行性は、ユーザ空間で実行されるべきタスクが多くある場合に特に有効であり、それは一般的にCPUへの負荷が高くなります。並行性は、問題を個々の部分に容易に並行して管理・スケジュールするように分割できる場合有効です。

訳注
並行計算と並列計算は違いに独立した概念ではありません。並行計算の方法として、マルチスレッド/マルチプロセス/複数台のマシンを用いた分散処理などがあり、並列計算は並行計算の一部になるようです。


本物のプログラマはHaskellを使う - 第10回 Haskellで学ぶ並列プログラミング(その1):ITpro

http://www.cs.tsukuba.ac.jp/~yas/cs/csys-2009/2009-12-04/index.html

Greenletは、あるソケットの相互作用が別のソケットと独立した相互作用を引き起こすような、並行性の典型的な例にあたるネットワークプログラミングにおいて特に秀でています。個々のGreenletはそれぞれ固有のコンテキストで動作するため、スレッドを用いることなく同期APIが利用できます。それは、仮想メモリカーネルのオーバヘッドという観点においてスレッドが非常に高負荷であるため、Greenletの利点となります(さらにPythonでスレッドを使用するのはGILのため機能が限定され負荷が高くなります)。並行性の代替手段としては、通常Twisted、libevent、libuv、node.jsなどになり、それらにおいてコードは同一の実行のコンテキストを共有し、イベントのハンドラーを登録します。

Greenletは先にあげたような理由で並行性を提供します。並行性は並列性ではありません。イベントのハンドラーの登録を隠蔽することや、スレッドをブロックする呼び出しをスケジューリングすることで、非同期APIへ変更せずにgeventは並行性を見せます。

以下が原文になります。

Greenlets provide concurrency but not parallelism. Concurrency is when code can run independently of other code. Parallelism is the execution of concurrent code simultaneously. Parallelism is particularly useful when there's a lot of work to be done in userspace, and that's typically CPU-heavy stuff. Concurrency is useful for breaking apart problems, enabling different parts to be scheduled and managed more easily in parallel.

Greenlets really shine in network programming where interactions with one socket can occur independently of interactions with other sockets. This is a classic example of concurrency. Because each greenlet runs in its own context, you can continue to use synchronous APIs without threading. This is good because threads are very expensive in terms of virtual memory and kernel overhead, so the concurrency you can achieve with threads is significantly less. Additionally, threading in Python is more expensive and more limited than usual due to the GIL. Alternatives to concurrency are usually projects like Twisted, libevent, libuv, node.js etc, where all your code shares the same execution context, and register event handlers.

It's an excellent idea to use greenlets (with appropriate networking support such as through gevent) for writing a proxy, as your handling of requests are able to execute independently and should be written as such.

Greenlets provide concurrency for the reasons I gave earlier. Concurrency is not parallelism. By concealing event registration and performing scheduling for you on calls that would normally block the current thread, projects like gevent expose this concurrency without requiring change to an asynchronous API, and at signficantly less cost to your system.