1

この質問から受け入れられた回答を使用しています。関連するコードは以下です。

import multiprocessing

def query_with_timeout(dbc, timeout, query, *a, **k):
  conn1, conn2 = multiprocessing.Pipe(False)
  subproc = multiprocessing.Process(target=do_query,
                                    args=(dbc, query, conn2)+a, 
                                    kwargs=k)
  subproc.join(timeout)
  if conn1.poll():
    return conn1.recv()
  subproc.terminate()
  raise Exception("Query %r ran for >%r" % (query, timeout))

def do_query(dbc, query, conn, *a, **k):
  cu = dbc.cursor()
  cu.execute(query, *a, **k)
  return cu.fetchall()

私の呼び出しは次のようになります。

res = query_with_timeout(dbconn, 30, "SELECT * FROM `table`)
print res

dbconn接続オブジェクトです。アプリケーションの他の場所 (このタイムアウト関数の外) で問題なく使用されます。

サブプロセスに参加し、30 秒間待機しているようです。if conn1.poll(): return conn1.recv()結果をポーリングするときは、コードのブロックに入ることはありません。代わりに、常に例外を受け取ります。

クエリが実行されることはわかっています (これは単純な選択です)。1 秒もかからずに実行されます。

私は何か見落としてますか?

4

1 に答える 1

1

さて、あなたが投稿したコードに基づいたいくつかのこと。まず、プロセスを実行する必要はありませんstart()。しかし、それはこの例を入力する際に​​あなたが犯した間違いではないでしょうか?

send()第二に、接続を介して何もしません。

これは、予想される動作を伴う上記の単純化されたバージョンです。

import multiprocessing
import time

def simple_example(wait, timeout, query):
    conn1, conn2 = multiprocessing.Pipe(False)
    subproc = multiprocessing.Process(target=do_query, args=(wait, query, conn2))
    subproc.start()
    subproc.join(timeout)
    if conn1.poll():
        return conn1.recv()
    subproc.terminate()
    raise Exception('Query %r ran for >%r' % (query, timeout))

def do_query(wait, query, conn):
    print query
    time.sleep(wait)
    conn.send(query)

res = simple_example(0, 2, 'foo')
res = simple_example(3, 2, 'foo')

ただし、これは単にサンプルコードの問題である可能性があります。

于 2012-06-15T20:43:24.370 に答える