3

DBusサービスとして利用できるMainObjectを作成しようとしています。このMainObjectは、他のオブジェクト/プロセスに常に応答し、アイテムを処理している間もこの非ブロッキングを維持する必要があります。そのため、アイテムは別のスレッドで次々に処理されます(キュースタイル)。DBusまたはコマンドラインを介してMainObjectにアイテムを追加できます。問題を示すために、サンプルを簡略化しました(dbusもコマンドラインもありません)。

私の問題は、「tt.join()」を再度有効にすると、アプリケーションは期待どおりに機能しますが、他のプロセスをブロックしていることです。当然のことながら、tt.joinは、別のスレッドが作業を終了するまでアプリケーションを待機させます。一方、「tt.join()」が無効のままの場合、アプリケーションは外部のdbusイベントをブロックしませんが、「ThreadTestdone!」には到達しません。(実際の出力を見てください)

私が欲しいのは、期待される出力ですが、アプリケーションは応答性を維持する必要があります。

#!/usr/bin/python2.5

import gobject
import threading
import re
import time

class ThreadTest(threading.Thread):

  def __init__(self):
    threading.Thread.__init__ (self)    
    print '  ThreadTest created!'

  def run(self):
    print '  ThreadTest running ...'
    time.sleep(1)
    print '  ThreadTest done!'
    return True

class MainObject():
  def __init__(self):
    self.timer = gobject.timeout_add(1000, self.update)
    self.loop  = gobject.MainLoop()
    print 'MainObject created!'

  def update(self):
    print 'MainObject updating ...'
    if self.check_running() == False:
      tt = ThreadTest()
      tt.start()
      #tt.join()
    return True

  def check_running(self):
    running = False
    expr = re.compile('ThreadTest')
    for threadstr in threading.enumerate():
      matches = expr.findall(str(threadstr))
      if matches:
        running = True
    return running  


mo = MainObject()
mo.loop.run()

期待される出力:

MainObject created!
MainObject updating ...
  ThreadTest created!
  ThreadTest running ...
  ThreadTest done!
MainObject updating ...
  ThreadTest created!
  ThreadTest running ...
  ThreadTest done!
MainObject updating ...
  ThreadTest created!
  ThreadTest running ...
  ThreadTest done!
MainObject updating ...
  ThreadTest created!
  ThreadTest running ...
  ThreadTest done!
MainObject updating ...
  ThreadTest created!
  ThreadTest running ...
  ThreadTest done!

実際の出力:

MainObject created!
MainObject updating ...
  ThreadTest created!
  ThreadTest running ...
MainObject updating ...
MainObject updating ...
MainObject updating ...
MainObject updating ...
MainObject updating ...
MainObject updating ...
MainObject updating ...
MainObject updating ...
MainObject updating ...
4

2 に答える 2

2

デフォルトのgobjectバインディングはマルチスレッド対応ではありません。インポートした直後に、次のことを試してくださいgobject

gobject.threads_init()
于 2010-01-05T15:30:52.687 に答える
0

Pythonのスレッドは罠になる可能性があります。実際、これは未解決の問題です。主な問題はGIL(Pythonのグローバルインタープリターロック)です。

これを克服するために彼らが発明した方法の1つは、「マルチプロセッシング」モジュール(python 2.6の新機能)です。これは「スレッド」インターフェイスを保持しますが、実際には別のプロセスでコードを実行します。しかし:メインの「スレッド」(つまり単一のプロセス)ですべてのdbusインタラクション、GUIなどを実行し、サブプロセス(文字列、リスト、辞書など)とデータを交換します...これは機能します大丈夫。

また、threading.enumerateの戻り値に特定の文字列が存在するかどうかを確認するためだけに、このすべての正規表現Voodoがなぜあるのか理解できません。Pythonには「in」演算子もあります(したがって、strのインデックスを使用したり、メソッドを検索したりする必要はありません)。

check_runningそのメソッド全体を次のように置き換えることができます。

def check_running(self):
    return 'ThreadTest' in str(threading.enumerate())
于 2010-01-05T14:02:57.500 に答える