Python 为什么打开文件时多处理不起作用?

Python 为什么打开文件时多处理不起作用?,python,multiprocessing,python-multiprocessing,Python,Multiprocessing,Python Multiprocessing,在我试用多处理池模块时,我注意到当我加载/打开任何类型的文件时,它都不起作用。下面的代码按预期工作。当我取消注释第8-9行时,脚本跳过池。apply_async方法,并且loopingTest从不运行 import time from multiprocessing import Pool class MultiClass: def __init__(self): file = 'test.txt' # with open(file, 'r') as

在我试用多处理池模块时,我注意到当我加载/打开任何类型的文件时,它都不起作用。下面的代码按预期工作。当我取消注释第8-9行时,脚本跳过
池。apply_async
方法,并且
loopingTest
从不运行

import time
from multiprocessing import Pool


class MultiClass:
    def __init__(self):
        file = 'test.txt'
        # with open(file, 'r') as f:  # This is the culprit
        #     self.d = f
        self.n = 50000000
        self.cases = ['1st time', '2nd time']
        self.multiProc(self.cases)
        print("It's done")

    def loopingTest(self, cases):
        print(f"looping start for {cases}")
        n = self.n
        while n > 0:
            n -= 1
        print(f"looping done for {cases}")

    def multiProc(self, cases):
        test = False
        pool = Pool(processes=2)
        if not test:
            for i in cases:
                pool.apply_async(self.loopingTest, (i,))
            pool.close()
            pool.join()



if __name__ == '__main__':
    start = time.time()
    w = MultiClass()
    end = time.time()
    print(f'Script finished in {end - start} seconds')

之所以会出现这种行为,是因为将文件描述符(
self.d
)保存到实例时调用
apply\u async
失败。调用
apply\u async(self.loopingTest,…)
时,Python需要pickle
self.loopingTest
将其发送到工作进程,这也需要pickle
self
。当您将打开的文件描述符保存为
self
的属性时,由于无法对文件描述符进行pickle,因此pickle会失败。如果在示例代码中使用
apply
而不是
apply\u async
,您自己就会看到这一点。您将得到如下错误:

Traceback (most recent call last):
  File "a.py", line 36, in <module>
    w = MultiClass()
  File "a.py", line 12, in __init__
    self.multiProc(self.cases)
  File "a.py", line 28, in multiProc
    out.get()
  File "/usr/lib/python3.6/multiprocessing/pool.py", line 644, in get
    raise self._value
  File "/usr/lib/python3.6/multiprocessing/pool.py", line 424, in _handle_tasks
    put(task)
  File "/usr/lib/python3.6/multiprocessing/connection.py", line 206, in send
    self._send_bytes(_ForkingPickler.dumps(obj))
  File "/usr/lib/python3.6/multiprocessing/reduction.py", line 51, in dumps
    cls(buf, protocol).dump(obj)
TypeError: cannot serialize '_io.TextIOWrapper' object
回溯(最近一次呼叫最后一次):
文件“a.py”,第36行,在
w=多类()
文件“a.py”,第12行,在_init中__
self.multiProc(self.cases)
文件“a.py”,第28行,multiProc格式
出去
get中第644行的文件“/usr/lib/python3.6/multiprocessing/pool.py”
提升自我价值
文件“/usr/lib/python3.6/multiprocessing/pool.py”,第424行,在任务处理中
放置(任务)
文件“/usr/lib/python3.6/multiprocessing/connection.py”,第206行,在send中
self.\u发送\u字节(\u ForkingPickler.dumps(obj))
文件“/usr/lib/python3.6/multiprocessing/reduce.py”,第51行,转储
cls(buf,协议).dump(obj)
TypeError:无法序列化'\u io.TextIOWrapper'对象

您需要更改代码,或者避免将文件描述符保存到
self
,只在worker方法中创建它(如果需要使用它),或者通过来控制类的pickle/unpickle过程。根据用例的不同,您还可以将传递给
apply\u async
的方法转换为顶级函数,这样
self
就不需要进行任何修改。

当我加载/打开任何类型的文件时,它不起作用是什么意思?它如何“不起作用”?你有错误吗?我对问题稍加修改,试图澄清OP的意思。看起来他们输入了“注释掉”,意思是“取消注释”。