12

Iはロックの優先順位付けは可能ですか?

  • つのプロセスは、いくつかの他のプロセスがそのリストからこれらの要素を消費する(およびそれらを削除)
  • multiprocessing.Manager().list())共有リストに要素を追加multiprocessingプログラムを有しています。それらはリスト内で処理するものがあるまで実行され、上記のプロセスは依然としてリストに追加されます。

ロックを実装しました(multiprocessing.Lock()経由)。リストに追加したり、削除したりしました。 1つの「フィーダー」プロセスと複数の(10〜40)「消費者」プロセスがすべてロックを競合し、消費者プロセスが高速であるため、「フィーダー」プロセスでロックを取得するのが困難になります。

ロックを取得する際に「優先度」の概念はありますか?私は "フィーダ"プロセスが他のものよりも優先してそれを取得することを望みます。

"フィーダ"プロセスがある間にロックを取得しようとする前に、 "コンシューマ"プロセスがランダムな時間待機することで問題を軽減しました。これは回避策ですが、それは醜く、ほとんど効果がありません(私はrandom.random()*n秒を待つプロセスを持っています。ここで、nはプロセスの数です。これは完全に構成された番号であり、おそらく間違っています)。

+0

がどのように "キュー" の概念が実現されていますか?あなたがロックのために来たときにプロセスをリストに追加するだけですか? –

+0

@ Ev.Kounis:はい、これは質問で言及したように、 'multiprocessing.Manager()。list()'です(これは 'multiprocessing.Queue()'ではありません) – WoJ

+0

どの要素が追加されて取得されたのですか?つまり、プロセスの優先順位を追跡する構造体(リスト?)を意味します。 –

答えて

0

これは完璧ではありませんが、それは動作する必要があります。

"フィーダー" で:

feeder_lock_object.lock() 
consumer_lock_object.lock() 
try: 
    ... 
finally: 
    feeder_lock_object.release() 
    consumer_lock_object.release() 

"消費者" で:

while True: 
    with consumer_lock_object: 
     if feeder_lock_object.is_locked: 
      continue 
     ... 

しかし、私はそれは時に良くなると思いますキューを使用します。

このメソッドを使用する場合は、ロックオブジェクトの実装方法に注意してください。これらのロックオブジェクトをグローバルパラメータとして作成するイニシャライザ関数を使用して、プールを初期化する必要があります。 thisを参照してください。

0

ロックの優先順位を変更しようとするのではなく、フィーダがコンシューマよりも優先順位が高くなるようにプロセス優先順位自体を変更してみてください。使用した回避策は基本的にこれをシミュレートしますが、効率は低くなります。 (os.setpriorityを使用)

サードパーティモジュールpsutilを使用し、Windows上でdocs

を参照してください、Unixでは

をプロセスの優先度を変更するには

this threadおよびPsutil Docsを参照してください。

1

フィーダがロックをブロックし、消費者がブロックしないようにします。だから、フィーダー用

​​

と消費者:

while True: 
    try: 
     locked = my_lock.acquire(blocking=False) 
     if locked: 
     do stuff 
    finally: 
     if locked: 
     my_lock.release() 
    time.sleep(seconds=10) 
関連する問題