ができるプログラムの構築にPythonのスタックフレームおよび実行を開始で任意のコードについて教えてください。
-
23-08-2019 - |
質問
ができるプログラムを構築しスタック(一つ以上のスタックフレーム)CPythonおよび実行を開始で任意のコードポイント?想像以下のシナリオ:
お持ちのワークフローエンジンがワークフローできる脚本にPythonの一部を構築します(例:アルゴリズムの研究を待って/加わる話をワークフローエンジンです。
ブロックに電話など、待ちに参加を設定するリスナー状態イベント-派遣エンジンの持続的なバッキングストアの一部の並べ替えができます。
お持ちのワークフローのスクリプトを無料でご利用をお待ち状態のエンジンを待ち、ある条件を示唆する。このセットのリスナーの派遣エンジンです。
ワークフロー-スクリプトの状況、関係スタックフレームを含むプログラムカウンター(または同等の状態が続を待機状態が発生日又はか月後に施行された。
中間のワークフローエンジンが停止し、再開始していなければいけない事を意味するのでプログラムにお店を再構築のコンテキストのワークフローを記述します。
イベントを派遣エンジン火災の場をお待ち状態をピック。
ワークフローエンジンを読み込みserialised状態およびスタックおよび再構成し、スレッドのスタックです。その後に続けて実行での待サービスが行われようとしていました。
の質問
できることを利用する更Pythonインタプリタ?でも、誰でもできるのでも一部の文書がカバーこのようなもの例をコードするプログラムにより構築していますのスタックフレームと実行の中では真ん中辺りに位置ブロックのコードについて教えてください。
編集: 明らかに'変更pythonインタプリタ',静かもしC APIを利用(りがある情報PyThreadStateこのためには?) もしっかり身につけるた行きたい書込処理の炉内構造物のPythonインタプリタをを変更したものです。
更新: 一部の初期の調査では、体感することができます。実行コンテキスト PyThreadState_Get()
.返り値はスレッドの状態 PyThreadState
(定義される pystate.h
する)への参照をスタックフレーム frame
.スタックフレームはtypedef structい PyFrameObject
, で定義される frameobject.h
. PyFrameObject
は分野 f_lasti
(道具 bobince るプログラムカウンタとして表現からのオフセットのコードブロックです。
この最後ですが、良いニュースがこのときの保全に実際のコンパイルされたコードブロックに対応することができるでしょうを再構築地元の人々のために多くのスタックフレームとして必要かを再開しています。いと思うんこすることは、理論的には可能でなく、更にpython interpereterがこのコードはおそらくするヒとの密な結合への特定のバージョンの通訳です。
の残りの問題としては
取引の国家と"佐賀'ロールバックするだけでなく、成のような形式のメタクラスのハッキングもご利用をO/Rマッパー.かったので、試作機で、一度くらいなので公正なうことがあります。
が堅調に推移serialising取引状況および任意の。これにより読み
__locals__
(から利用できますスタックフレーム)programatically構築の呼酢漬けにしてあります。しかし、どうなるかはわからない場合、gotchasができます。バージョンアップのワークフロー.これはややtrickierとしてのシステムを提供していない任意の象徴的なアンカーのためのワークフローのノード。私たちには、アンカー そのためにいう特定のオフセットのすべてのスタート地点として、そして電子メールと電話によって、新しいバージョン。も実現可能な手動でも疑いのは難しいので自動化する.この最大の障害の場合をサポートしていきたいです。
更新2: PyCodeObject
(code.h
ての一覧をaddr(f_lasti
)->の行番号にマッピング PyCodeObject.co_lnotab
(正しい場合は違います。このトランでもご利用いただい円滑な移行プロセスを更新ワークフローを新しいバージョン、冷凍指導のポインタがマッピングされ、適切な場所に新しいスクリプト行の行番号まだかなりの乱れがもう少し期待できます。
更新3: と思うのは、その答えが Stacklessます。 きを停止務serialiseします。いたのかということも仕事のスタックしています。
解決 5
標準CPythonので、これは、スタック内のCとPythonデータの混合物によって複雑になります。コールスタックを再構築すると同時に再構築するためにCスタックを必要とします。それはCPythonの特定のバージョンに実装潜在的にしっかりと夫婦可能性があるのでこれは本当にあまりにもハードバスケットに入れます。
StacklessのPythonは、箱から出して必要な機能のほとんどを与える、タスクレットを漬けすることができます。
他のヒント
通常のPythonディストリビューションに含まexpatのPythonバインディングはprogramticallyスタックフレームを構築しています。しかし注意して、それが文書化されていないと、民間のAPIに依存しています。
ます。http://svn.python。 ORG /ビュー/パイソン/トランク/モジュール/ pyexpat.c?REV = 64048&ビュー=自動の
あなたは、一般的に、私が見継続、ありたいのは、すでにこの質問にタグです。
あなたは、システム内のすべてのコードで動作する能力を持っている場合は、は、あなたが試してみたいこと このようにそれをやってではなく、インタプリタのスタックの内部を扱います。私はこれを永続化する方法を簡単にはわからない。
http://www.ps.uni-sb.de /~duchier/python/continuations.htmlする
スクリプトがマネージャにアクションオブジェクトを提出するように、実際には、私はあなたのワークフローエンジンを構築します。管理者は、任意の時点で一連のアクションを酸洗し、可能性があります それらがロードされ、(アクションの提出を再開することによって)再び実行を開始する。
つまり:あなた自身の、アプリケーションレベル、スタックを作る
スタックレスのpythonは...おそらく最高です。 stackless
はpythonでのすべてのをシリアル化、加えてそのタスクレットができます。あなたは、標準のPythonディストリビューションに滞在したい場合は、その後、私は強い<シリアライズすることができた、ディルを使用したいです>ほとんどののpythonで何かます。
>>> import dill
>>>
>>> def foo(a):
... def bar(x):
... return a*x
... return bar
...
>>> class baz(object):
... def __call__(self, a,x):
... return foo(a)(x)
...
>>> b = baz()
>>> b(3,2)
6
>>> c = baz.__call__
>>> c(b,3,2)
6
>>> g = dill.loads(dill.dumps(globals()))
>>> g
{'dill': <module 'dill' from '/Library/Frameworks/Python.framework/Versions/7.2/lib/python2.7/site-packages/dill-0.2a.dev-py2.7.egg/dill/__init__.pyc'>, 'c': <unbound method baz.__call__>, 'b': <__main__.baz object at 0x4d61970>, 'g': {...}, '__builtins__': <module '__builtin__' (built-in)>, 'baz': <class '__main__.baz'>, '_version': '2', '__package__': None, '__name__': '__main__', 'foo': <function foo at 0x4d39d30>, '__doc__': None}
ディルは、あなたがpickle
を使用し、あなたが本当にその後、ちょうどディルをインポートすると、魔法、それはサードパーティのコードをmonkeypatchingせずに動作させることができ、それを編集することはできませんいくつかのブラックボックスのコードを持っているので、もしそれが、pickle
レジストリにタイプのレジスタ。
ここでは全体のインタプリタセッションを酸洗dill
だ...
>>> # continuing from above
>>> dill.dump_session('foobar.pkl')
>>>
>>> ^D
dude@sakurai>$ python
Python 2.7.5 (default, Sep 30 2013, 20:15:49)
[GCC 4.2.1 (Apple Inc. build 5566)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import dill
>>> dill.load_session('foobar.pkl')
>>> c(b,3,2)
6
dill
もいくつかの良いツールはあなたが理解助けるためをしています何があなたのコードが失敗したときに、あなたの酸洗の失敗の原因となっている。
またのために尋ねた?
IPython のファイルにインタプリタセッションを保存するためにdill
を使用することができます。 https://nbtest.herokuapp.com /github/ipython/ipython/blob/master/examples/parallel/Using%20Dill.ipynbする
klepto のは避けメモリ内、ディスクへの、またはそれにデータベースキャッシュをサポートするためにdill
を使用再計算。 https://github.com/uqfoundation/klepto/blob/master/tests /test_cache_info.pyする
神秘のは、それだとオプティマイザの状態を保存することで、大規模な最適化ジョブのチェックポイントを保存するためにdill
を使用しています進行中。 https://github.com/uqfoundation/mystic/blob/master/tests /test_solver_state.pyする
オブジェクトまたはセッションの状態を保存するためにdill
を使用夫婦他のパッケージがあります。
あなたは例外をスローし、バックトレースバック内に沿って一つのフレームを踏んで、既存のスタックフレームをつかむことができました。問題は、コードブロックの中央(frame.f_lasti)で実行を再開するために提供方法がないです。
それは彼らがPythonのは、既存と相互作用することができる合理的な方法を考えるためにトリッキーだが、「再開可能な例外は」本当に面白い言語のアイデアであるブロック「で」「/最後にしてみてください」と。
今のところ、これを行うための通常の方法は、そのコントローラーに別の文脈でワークフローを実行するためにスレッドを使用することです。 (または、コルーチン/ greenletsあなたがそれらをコンパイルする気にしない場合)。
私が解決する問題の同じ種類を持っています。私は、元のポスターが行うことを決めたのだろうか。
スタックレスはそれがある限りは関連する「邪魔」Cスタック(邪魔がフレージングの私の選択された)がないとタスクレットをpickle化できると主張しています。
私はおそらく、私は本当にかかわらず、明示的なステートマシンを書きたくないeventletを使用し、「状態」酸洗のいくつかの方法を考え出すだろう..
どの程度使用して JOBLIB の?
私は、これはあなたが望むものはかなりよく分からないが、段階が持続することができたのワークフローを持つことのアイデアを合わせているようです。 JOBLIBのユースケースは、私は、これはあなたがここでやろうとしているものであるか、何かもっと複雑かどうかわからないんだけど、再計算を避けるためであると思われる?