2012-02-19 6 views
1

私はPythonでいくつかの実験をすることを考えていました。 javascriptのsetTimeoutやsetIntervalのような機能をいくつか紹介して、イベントループを開始するためのブロッキング呼び出しを行わずに何らかの非同期動作を移植したいと考えています。Python GILをCモジュールでバイパスすることはできますか?

はのは(今もちろん動作していない)、この例を見てみましょう:

from mymod import set_timeout # of course we love the PEP8 :) 
import sys, time 

def say_finished(): 
    time.sleep(2) # waiting, suppose here to have some blocking behaviour 
    sys.stdout.write("\nSee you!") 

sys.stdout.write("Hello, ") 
set_timeout(say_finished, 2000) # supposing we have msec granularity 
sys.stdout.write("World!") 

私はjavascriptのような挙動をしていたいのです。 set_timeoutがGILのために新しいスレッドを開始していた場合、新しいスレッドは終了するまでメインスレッドをブロックするので、 "Hello、\ nSee you!World"を出力します。

set_timeoutがCコードでposixスレッドを使用すると、この問題を回避できますか? これはPython C/APIとの統合であり、GILをバイパスできるかどうか、またはAPI自体もGILによってブロックされているかどうかわかりません(私は試してみましたが、今は勉強していますドキュメントと私は自分自身を試して準備ができていない)。

これは、次のようになります。印刷「こんにちは、」 - >実行SET_TIMEOUT(つまり、インタプリタがプログラムの実行を進めるためにできるように返す必要があります) - >印刷「の世界!」 - >外部スレッドが実行されている間は生きている - >コールバック "say_finished" - >終了。私はそれがインタプリタ自体を編集することが必要であろうと思わせる何か

は、「外部のスレッドが実行されている間生き続ける」という部分です。

新しいプロセスが作成するオーバーヘッドのために、プロセスを使用したくありません。

私はPythonの構文を愛し、私はそれで、このアプローチを使用したいので、「その後、Javascriptを使用して」言わないでください。

+0

あなたが書いていることはほぼ正確に 'threading.Timer'です。 http://docs.python.org/library/threading.html#timer-objects –

答えて

2

私はあなたがGILについて混乱していると思います。これは、実行中のすべてのスレッドを定期的にスワップすることによってコードがスレッドセーフであることを保証する、VMの実装の詳細です。すべてのVMはスレッド安全性を確保するために何らかの方法を必要としますが、GILは必ずしもその最速または最善の実装ではありませんが、アプリケーションプログラマにとって心配するものではありません。

threadingモジュールを使用して複数のスレッドでコードを実行できます。または、適切な並列性が本当に必要な場合は、別のOSプロセスでコードを実行する「multiprocessing」モジュールを使用し、「GILをバイパスします。それは価値があります。具体的に非同期のものが必要な場合は、この種のものを提供する新しいfuturesモジュールがあります。実際にを一定期間眠る必要がある場合は、time.sleepに電話してください。

いずれかの方法で、何かハイレベルに固執すると、独自のアプリケーション固有のタイミングとスケジューリングをやろうとしているよりも発生しやすいので、以下のエラー、それは解決するために、単純な問題ではありません!

+0

GILは、ただ1つのスレッド*が一度に*実行することを保証します。ですから、上記のコードを 'threading'を使って実行すると、すべてのスレッドが2秒間ブロックされます。私はマルチプロセスがトリックを行うだろうが、私は上記のようにそれを避けたいと思います。もちろん、完全なスケジューラはあまりにも多くの作業が必要なので、私は目的別のスレッドを行うことを考えていました。私はposixスレッドを使用してカウンタを実行し、有効期限が切れたときにメインスレッドをブロックせずに "say_finished"を呼び出します。 –

+0

この例の 'time.sleep'は、非同期スレッドの実行をブロックするCPU集約型のジョブをエミュレートするだけです。 –

+0

'時間。sleep() 'は実行中のスレッドのみをブロックし、GILを解放するので、他のスレッドも実行できます。 CPUを大量に使用するジョブがC言語で実行されている場合は、GILもリリースできます。それがPythonであれば、両方のスレッドは引き続き実行されますが、別々のコアに置くのではなく、スレッド間で切り替わります。 –

関連する問題