0

誰かが私を理解するのを手伝ってくれることを願っています。iPython ノートブックで 2 つの異なる並列ビューを作成しようとしています。最初のビューには ID 0 のプロセッサがあり、2 番目のビューには残りのすべてのプロセッサがあります。各ビューにプレフィックスを関連付けて、さまざまなプロセッサでさまざまなことを簡単に実行できるようにします。

2 番目のビューのプロセッサを使用して長い計算を行うバックグラウンド スレッドを起動します。それがバックグラウンドで実行されている間に、最初のビューを使用してコマンドを実行しようとしましたが、機能しません。次のエラーが表示されます: ValueError: '' is not in list.

ここでやろうとしていることを実行する方法があるかどうか、またはこれがサポートされていない動作であるかどうか疑問に思っています。つまり、異なるプロセッサを使用して 2 つの異なるビューを作成したいと考えています。ビュー間でプロセッサが共有されることはありません。次に、1 つのビューを使用するバックグラウンド タスクを実行しながら、同時に他のビューを無関係なタスクに使用できるようにしたいと考えています。

エラーが発生する小さなスクリプトの例を次に示します。ノートブックを直接投稿する方法がわからないので、ノートブックから生成された python スクリプトをコピーして貼り付けただけです。

# <codecell>

from IPython import parallel
cli = parallel.Client()

# <codecell>

view1 = cli[0]
view1.block = True
view1.activate("_one")

# <codecell>

view2 = cli[1:]
view2.block = True
view2.activate("_two")

# <codecell>

%px_two import time
def backFunc():
    for i in range(10):
        %px_two time.sleep(5)
        %px_two print "In bg thread"

# <codecell>

from IPython.lib import backgroundjobs as bg
bgJob = bg.BackgroundJobManager()
bgJob.new('backFunc()')

# <codecell>

%px_one import time
def foreFunc():
    for i in range(10):
        %px_one time.sleep(1)
        %px_one print "In fg thread"


# <codecell>

foreFunc()

forFunc() が実行されるとすぐに、エラーが発生します。

ValueError: '<IDS|MSG>' is not in list

何かご意見は?誰でもアイデアをいただければ幸いです。

4

1 に答える 1

1

簡潔な答え

クライアントが使用するソケットはスレッドセーフではないため、複数のスレッドで同時に使用することはできません。クラスターを同時に使用できますが、バックグラウンド タスク用に別のクライアントを作成する必要があります。これには独自のソケット セットがあります。

rc = parallel.Client()
rc2 = parallel.Client()

view1 = rc[0]
view2 = rc2[1:]

そして、残りは期待どおりに機能するはずです。

PS: どうしたの

Client オブジェクトは、ほとんどがソケットのコレクションに関する API です。各クライアントには独自のソケット セットがあり、1 つのクライアントのすべてのビューは同じソケットを使用します。これらのソケットを複数のスレッドで共有すると、あるスレッドが別のスレッド向けのメッセージの一部を取得して、メッセージが文字化けする可能性があります。

各メッセージは、実際にはzmq.Socket.send/recv_multipartで送受信されるマルチパート メッセージ zeromq メッセージです。

multipart = []
for i in range(nparts):
    multipart.append(socket.send/recv())

2 つのスレッドが同じソケットで同時にこれを実行している場合、メッセージがインターリーブされる可能性があるため、2 つのメッセージを取得する代わりに:

['a1', 'a2', 'a3'], ['b1', 'b2', 'b3']

我々が得る

['a1', 'a2', 'b1', 'b2', 'b3'], ['a3']

あなたが見ている問題を引き起こしています。最も簡単な修正方法は、異なるスレッドで異なるソケットを使用することです。別の修正方法は、ロックを使用して、マルチパート メッセージがアトミックに受信されるようにすることです。スレッドごとにソケットを分離すると、ロックの必要性を回避できますが、同時スレッドの数に比例して、使用する必要があるソケットの数が増加します。

PPS ...しかし、IPython.parallelは非同期です

最後に、バックグラウンド ジョブを使用している理由をお尋ねします。クライアントは通常、エンジンからの結果を待機しないため、説明したタスクを実行するためにスレッドを使用する必要はありません。IPython.parallel は本質的に非同期であるため、新しいジョブを送信したり、対話型セッションでローカルに作業したりするために、ジョブが終了するのを待つ必要はありません。block=True通常、デバッグ以外に使用することはお勧めしません。

于 2014-12-01T22:50:37.930 に答える