python3 多进程 multiprocessing 报错 AttributeError: ‘ForkAwareLocal‘ object has no attribute ‘connection‘

目录

错误代码

报错信息

错误原因

解决方法


错误代码

python多进程管理manager时候,当不使用join对当前进程(主进程)进行阻塞时会报错,具体代码及错误如下:

from multiprocessing import Process, Manager
import time
import os
 
 
def info(title):
    print(title)
    print('module name:', __name__)
    print('parent process:', os.getppid())
    print('process id:', os.getpid())
    print("\n\n")
 
 
 
def f(d, l,n):
    info('\033[32;1m subprocess line\033[0m')
    d[1] = '1'
    d['2'] = 2
    d[0.25] = None
    l.append(n)
    print(l)
 
 
if __name__ == '__main__':
    info('\033[32;1mmain process line\033[0m')
    with Manager() as manager:
        d = manager.dict()
 
        l = manager.list(range(5))
        p_list = []
        for i in range(10):
            p = Process(target=f, args=(d, l,i))
            p_list.append(p)
            # p.join()
        for p in p_list:
            p.start()

报错信息

Process Process-11:
Traceback (most recent call last):
  File "/usr/lib/python3.4/multiprocessing/managers.py", line 724, in _callmethod
    conn = self._tls.connection
AttributeError: 'ForkAwareLocal' object has no attribute 'connection'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.4/multiprocessing/process.py", line 254, in _bootstrap
    self.run()
  File "/usr/lib/python3.4/multiprocessing/process.py", line 93, in run
    self._target(*self._args, **self._kwargs)
  File "managerTest.py", line 19, in f
    d[1] = '1'
  File "<string>", line 2, in __setitem__
  File "/usr/lib/python3.4/multiprocessing/managers.py", line 728, in _callmethod
    self._connect()
  File "/usr/lib/python3.4/multiprocessing/managers.py", line 715, in _connect
    conn = self._Client(self._token.address, authkey=self._authkey)
  File "/usr/lib/python3.4/multiprocessing/connection.py", line 495, in Client
    c = SocketClient(address)
  File "/usr/lib/python3.4/multiprocessing/connection.py", line 624, in SocketClient
    s.connect(address)
FileNotFoundError: [Errno 2] No such file or directory

错误原因

启动工作进程后 主进程立即就结束了,创建multiprocessing.Manager的进程完成执行后,Manager服务器将关闭,这意味着您的共享列表对象现在无用了。

发生这种情况是因为Manager对象将其shutdown函数注册为multiprocessing模块的" finalizer",这意味着它将在进程退出之前运行。这是在BaseManager.__init__中注册它的代码:

# register a finalizer
self._state.value = State.STARTED
self.shutdown = util.Finalize(
    self, type(self)._finalize_manager,
    args=(self._process, self._address, self._authkey,
          self._state, self._Client),
    exitpriority=0
    )

这是实际执行关闭操作的代码:

@staticmethod
def _finalize_manager(process, address, authkey, state, _Client):
    '''
    Shutdown the manager process; will be registered as a finalizer
    '''
    if process.is_alive():
        util.info('sending shutdown message to manager')
        try:
            conn = _Client(address, authkey=authkey)
            try:
                dispatch(conn, None, 'shutdown')
            finally:
                conn.close()
        except Exception:
            pass

        process.join(timeout=1.0)
        if process.is_alive():
            util.info('manager still alive')
            if hasattr(process, 'terminate'):
                util.info('trying to `terminate()` manager process')
                process.terminate()
                process.join(timeout=0.1)
                if process.is_alive():
                    util.info('manager still alive after terminate')

    state.value = State.SHUTDOWN
    try:
        del BaseProxy._address_to_local[address]
    except KeyError:
        pass

解决方法

在主进程中 对子进程进行 join 等待

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
`AttributeError: 'ForkAwareLocal' object has no attribute 'connection'` 这个错误通常是由于在多进程环境中使用了不支持共享的对象或属性导致的。这可能是因为你正在尝试在多个进程中访问一个本地对象,而该对象在进程之间无法共享。 一个常见的例子是在多进程中使用 `multiprocessing.Pool` 对象时发生此错误。`multiprocessing.Pool` 使用 `Fork` 方法来创建子进程,但这种方法会导致某些本地对象无法共享,从而引发上述错误。 解决这个问题的方法是使用 `multiprocessing.Manager` 对象来创建可共享的对象或属性。你可以使用 `manager.Namespace()` 来创建一个命名空间对象,或者使用 `manager.Value()` 或 `manager.Array()` 来创建共享的值或数组。 以下是一个示例,演示如何在多进程中共享一个属性: ```python from multiprocessing import Process, Manager def worker_func(shared_dict): shared_dict.connection = "example" if __name__ == '__main__': manager = Manager() shared_dict = manager.Namespace() process = Process(target=worker_func, args=(shared_dict,)) process.start() process.join() print(shared_dict.connection) ``` 在这个示例中,我们使用 `manager.Namespace()` 创建了一个可共享的命名空间对象 `shared_dict`,然后在子进程中给它添加了一个属性 `connection`。最后,在主进程中打印了这个共享属性。 希望这个示例能帮助你解决 `AttributeError: 'ForkAwareLocal' object has no attribute 'connection'` 错误。如果你有进一步的问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值