0

PyPy コールバックは、Python オブジェクトのメソッドとして (簡単に) 実装すると (無限ループで) 完全に機能しますが、Python オブジェクトを別のマルチプロセッシング プロセスに移動すると、約 100 回の反復後にセグメンテーション違反が発生します。

私が持っているメインコードでは:

import multiprocessing as mp

class Task(object):

    def __init__(self, com, lib):

        self.com = com # communication queue
        self.lib = lib # ffi library
        self.proc = mp.Process(target=self.spawn, args=(self.com,))
        self.register_callback()

    def spawn(self, com):
        print('%s spawned.'%self.name)
        # loop (keeping 'self' alive) until BREAK:
        while True:
            cmd = com.get()
            if cmd == self.BREAK:
                break
        print("%s stopped."%self.name)

    @ffi.calback("int(void*, Data*"):   # old cffi (ABI mode)
    def callback(self, data):
        # <work on data>
        return 1

    def register_callback(self):
        s = ffi.new_handle(self)
        self.lib.register_callback(s, self.callback)  # C-call

複数のタスクが同数のコールバックを同時に処理する必要があるという考え方です。特に最初の〜100回程度の反復では問題なく動作するため、セグメンテーション違反の原因はわかりません。大変助かりました!

4

1 に答える 1

0

解決

ハンドル「s」は、「register_callback()」から戻るときにガベージ コレクションされます。ハンドルを 'self' の属性にして渡すと、ハンドルが生き続けます。

標準の CPython (cffi 1.6.0) は、最初の繰り返しでセグメンテーション違反を起こし (つまり、gc はすぐに実行されました)、重要な情報を示すエラー メッセージを表示しました。一方、PyPy は約 100 回の反復後にメッセージを表示せずにセグメンテーション違反を起こしました...どちらも現在は正常に動作しています。

于 2016-05-14T19:32:15.377 に答える