V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
pppguest3962
V2EX  ›  Python

请教 concurrent.futures 的多进程 ProcessPoolExecutor, sumit 提交任务,如何正确把字典作为参数传入?

  •  
  •   pppguest3962 · 2020-09-22 16:30:19 +08:00 · 1471 次点击
    这是一个创建于 1283 天前的主题,其中的信息可能已经有所发展或是发生改变。

    只是个伪代码例子, 原代码量大,只能弄了个结构上一致的简单的例子,
    procFun 在没套入到多进程的时候,工作得很好,是一个闭包,不会与其它什么的造成干涉。。。

    BABTaskDict = {'TkNum':32,
                             'TkString':'test String'}
    
    def procFun(taskInfo):
         taskNumber = taskInfo.get('TkNum')
         taskString = taskInfo.get('TkString')
         ...
         ...
         pass
    
    with concurrent.futures.ProcessPoolExecutor(max_workers=3) as executor:
                 to_do = []
                #executor.submit 返回 future 实例
                future = executor.submit(procFun, BABTaskDict ) # 方式 1
                # 方式 2 future = executor.submit(procFun, *BABTaskDict )
                # 方式 3 future = executor.submit(procFun, **BABTaskDict )
                to_do.append(future)
    

    用了方式 1 的方法,会有如下提示:

    Traceback (most recent call last):
      File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\multiprocessing\queues.py", line 234, in _feed
        obj = _ForkingPickler.dumps(obj)
      File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\multiprocessing\reduction.py", line 51, in dumps
        cls(buf, protocol).dump(obj)
    TypeError: can't pickle _thread.lock objects
    

    用了方式 2 的方法,future.result()有如下:

      File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\concurrent\futures\_base.py", line 432, in result
        return self.__get_result()
      File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\concurrent\futures\_base.py", line 384, in __get_result
        raise self._exception
    TypeError: procFun() takes 1 positional argument but 17 were given
    

    用了方式 3 的方法,与方式 1 一样,
    是不是姿势不对?
    没其它选择,info 字典内容必须传进去,散写逐个参数,非常麻烦的。。。

    3 条回复    2020-09-22 19:41:07 +08:00
    xiaolinjia
        1
    xiaolinjia  
       2020-09-22 16:45:05 +08:00
    方式 1 的写法没问题,报那错是因为多进程在 windows 下要用 pickle 模块将环境的所有对象序列化,再 copy 一份给其他进程。所以是 procFun 函数里面有什么对象是不能 pickle 序列化吧。
    VYSE
        2
    VYSE  
       2020-09-22 17:07:33 +08:00
    taskInfo 这个 dict 里存了 thread lock, 所以不能序列化传递到子进程
    pppguest3962
        3
    pppguest3962  
    OP
       2020-09-22 19:41:07 +08:00
    醍醐灌顶,谢谢两位,找到原因了,多线程 /进程环境不同,我在在 taskInfo 里,就把 queen 队列的地址传进去使用了,
    ltQueen = queue.LifoQueue()
    taskInfo = {'ltQueen': ltQueen}
    其实很希望能在子进程里,能做 put 任务到主线程 /进程的队列 ltQueen 的操作,我看看试试能不能解决这个问题。。。,如果不成功,还是会发帖请教~~
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5392 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 07:04 · PVG 15:04 · LAX 00:04 · JFK 03:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.