2012-04-05 11 views
2

私は最近、マルチプロセッシングを私たちのソフトウェアに取り入れるという課題に直面しました。サブプロセスを生成するメインプロセスが必要です。メインプロセスにログ情報を送信する方法が必要です。これは主に、使用するモジュールが警告オブジェクトとエラーメッセージをログオブジェクトに書き込むため、これらのメッセージをメインプロセスで実行されるguiに表示したいからです。Python 3:ロギングにマルチプロセッシングキューを使用する

明らかなアプローチは、puts()をキューに入れたwrite()メソッドを使用して小さなクラスを作成し、このクラスをロギングストリームハンドラで使用することでした。メインプロセスは、このキューからテキストをguiに送信する()。しかし、これは動作していないようだと私は理由を知らない

私は問題を示すためにいくつかのサンプルコードを書いた。ロギング・オブジェクトを使用してサブプロセスにキューを書き込んだ後、メイン・プロセスはキューから読み込みを試みますが失敗します。誰かがこれに間違っていることを理解するのを助けることができますか?

私は出力があることを期待
import time, multiprocessing, queue, logging 

class FileLikeQueue: 
    """A file-like object that writes to a queue""" 
    def __init__(self, q): 
     self.q = q 
    def write(self, t): 
     self.q.put(t) 
    def flush(self): 
     pass 


def func(q): 
    """This function just writes the time every second for five 
    seconds and then returns. The time is sent to the queue and 
    to a logging object""" 

    stream = FileLikeQueue(q) 

    log = logging.getLogger() 
    infohandler = logging.StreamHandler(stream) 
    infohandler.setLevel(logging.INFO) 
    infoformatter = logging.Formatter("%(message)s") 
    infohandler.setFormatter(infoformatter) 
    log.addHandler(infohandler) 

    t1 = time.time() 
    while time.time() - t1 < 5: #run for five seconds 
     log.info('Logging: ' + str(time.time())) 
     q.put('Put: %s' % str(time.time())) 
     time.sleep(1) 



def main(): 
    q = multiprocessing.Queue() 
    p = multiprocessing.Process(target=func, args=(q,)) 
    p.start() 

    #read the queue until it is empty 
    while True: 
     try: 
      t = q.get() 
     except queue.Empty: 
      break 
     print(t) 


if __name__ == '__main__': 
    main() 

Logging: 1333629221.01 
Put: 1333629221.01 
Logging: 1333629222.02 
Put: 1333629222.02 
Logging: 1333629223.02 
Put: 1333629223.02 
Logging: 1333629224.02 
Put: 1333629224.02 
Logging: 1333629225.02 
Put: 1333629225.02 

しかし、私が得ることである:

Put: 1333629221.01 
Put: 1333629222.02 
Put: 1333629223.02 
Put: 1333629224.02 
Put: 1333629225.02 

だから、FUNCでPUT()操作は()動作しますが、ロギングはdoesnの't。どうして?

ありがとうございます。

+1

私はコードを掘り下げませんでしたが、マルチプロセッシング環境にログインしようとすると、私が書いた[この回答](http://stackoverflow.com/a/9823098/1132524)が見つかるかもしれません。ずいぶん前に、便利です。 –

+0

このRikのおかげで、これも役に立ちます。 –

答えて

3

あなたの問題は、ロギングモジュールの構成である。

あなたはlog.setLevel(logging.INFO)を呼び出す必要があります。デフォルトのログレベルはWARNINGなので、ログは無効です。

ハンドラオブジェクトでsetLevelを呼び出しましたが、ロギングされたメッセージはロガーによってフィルタリングされているためハンドラには届きません。デフォルトですべてのメッセージを処理するため、ハンドラ自体でsetLevelに電話する必要はありません。

+0

あなたは正しいです!私は前にそれを見ていなかったのは残念です。 –

関連する問題