跨多个进程在运行时更新字典的问题

时间:2018-02-11 02:47:55

标签: python-3.x python-multiprocessing

我尝试使用pygame配置一些可以在运行时动态更改/更新的键绑定。您可以在下面看到我的第一个原型尝试。我收到了一条令我困惑的错误信息。它在初始化期间抱怨多处理/ connection.py无法访问' Pitch'在test.py.

Traceback (most recent call last):
  File "/opt/pycharm-community-2017.2.3/helpers/pydev/pydevd.py", line 1599, in <module>
    globals = debugger.run(setup['file'], None, None, is_module)
  File "/opt/pycharm-community-2017.2.3/helpers/pydev/pydevd.py", line 1026, in run
    pydev_imports.execfile(file, globals, locals)  # execute the script
  File "/opt/pycharm-community-2017.2.3/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "/home/jesse/code/pygame_controller/test.py", line 56, in <module>
    test_rpyc()
  File "/home/jesse/code/pygame_controller/test.py", line 42, in test_rpyc
    i = InputProcess(mapping)
  File "/home/jesse/code/pygame_controller/input_rpc.py", line 111, in __init__
    i = Input(mapping)
  File "/home/jesse/code/pygame_controller/input_rpc.py", line 58, in __init__
    set_mapping(mapping)
  File "/home/jesse/code/pygame_controller/input_rpc.py", line 52, in set_mapping
    _mapping.update(mapping)
  File "<string>", line 2, in update
  File "/usr/lib64/python3.5/multiprocessing/managers.py", line 732, in _callmethod
    raise convert_to_error(kind, result)
multiprocessing.managers.RemoteError: 
---------------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib64/python3.5/multiprocessing/managers.py", line 228, in serve_client
    request = recv()
  File "/usr/lib64/python3.5/multiprocessing/connection.py", line 251, in recv
    return ForkingPickler.loads(buf.getbuffer())
AttributeError: Can't get attribute 'Pitch' on <module '__main__' from '/home/jesse/code/pygame_controller/test.py'>
---------------------------------------------------------------------------

当我调试时,在connection.py内部,我可以查看整个映射字典。看来connection.py有dict对象,这就是为什么我很困惑为什么它最终会抛出一个错误。多进程模块是否无法访问namedtuple&#39; Pitch&#39;?我可以改变&#39; Pitch&#39; namedtuples到整数然后这段代码工作正常。是否有更好的方法来更新映射,可能使用rpyc?如果我不能在这里取得进展,Rpyc就是我接下来的原型。

test.py

from collections import namedtuple
from input import event_queue, InputProcess

Pitch = namedtuple('Pitch', 'value')

mapping = {
    'keyboard': {
        'w': {  # key
            'key_down': Pitch(-1.0),  # event
            'key_up': Pitch(0.0),  # event
        },
    },
}


def test():
    i = InputProcess(mapping)
    i.start()

    while True:
        event = event_queue.get()
        print(event)


if __name__ == '__main__':
    test()

input.py

import pygame
from multiprocessing import Manager, Process

_manager = Manager()
_mapping = _manager.dict()

event_queue = _manager.Queue()


def initialize(joystick=True):
    """Initialize pygame & joystick"""
    ...


def set_mapping(mapping):
    """Change the current keyboard/joystick mappings"""
    global _mapping

    for k, _ in _mapping.items():
        _mapping.pop(k)

    _mapping.update(mapping)


class Input(object):
    def __init__(self, mapping=None):
        if mapping is not None:
            set_mapping(mapping)

    @staticmethod
    def run():    
        while True:
            event = pygame.event.wait()

            # handle event


class InputProcess(object):
    def __init__(self, mapping=None):
        initialize()
        i = Input(mapping)

        self.process = Process(target=i.run)

    def start(self):
        self.process.start()

    def stop(self):
        self.process.terminate()
        self.process.join()

1 个答案:

答案 0 :(得分:0)

这是关键。

AttributeError: Can't get attribute 'Pitch' on <module '__main__' from '/home/jesse/code/pygame_controller/test.py'>

test.py正在__main__运行。如果您创建的新文件可以导入所需内容并从那里运行,那么它将能够访问Pitch中的test.py

示例:

example.py

from .test import test

if __name__ == '__main__':
    test()
相关问题