不能在python函数中使用多处理

Can't use multiprocessing in python function

我是Python的初学者,我尝试将多处理放到一个函数中,但是Python给了我一个错误。

请参考以下原始代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from multiprocessing import Process
import time
def func1():
    print('test1')
    time.sleep(10)  
def func2():
    print('test2')
    time.sleep(5)
if __name__ == '__main__':
    p_func1 = Process(target=func1)
    p_func2 = Process(target=func2)
    p_func1.start()
    p_func2.start()
    p_func1.join()
    p_func2.join()  
    print('done')

它运行良好,给出了我需要的正确结果。

但是,当我尝试将多处理代码放入函数时:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from multiprocessing import Process
import time

def test_multiprocessing():
    def func1():
        print('test1')
        time.sleep(10)  
    def func2():
        print('test2')
        time.sleep(5)
    if __name__ == '__main__':
        p_func1 = Process(target=func1)
        p_func2 = Process(target=func2)
        p_func1.start()
        p_func2.start()
        p_func1.join()
        p_func2.join()  
        print('done')

test_multiprocessing()

下面是我的错误,我可以知道如何解决这个问题吗?我想把多处理放到功能中的原因是因为那里有一个现有的代码,我不想对代码进行重大更改以支持多处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Traceback (most recent call last):
  File"multipleprocessing.py", line 20, in <module>
    test_multiprocessing()
  File"multipleprocessing.py", line 14, in test_multiprocessing
    p_func1.start()
  File"C:\Users\User\AppData\Local\Programs\Python\Python36\lib\multiprocessing
\process.py"
, line 105, in start
    self._popen = self._Popen(self)
  File"C:\Users\User\AppData\Local\Programs\Python\Python36\lib\multiprocessing
\context.py"
, line 223, in _Popen
    return _default_context.get_context().Process._Popen(process_obj)
  File"C:\Users\User\AppData\Local\Programs\Python\Python36\lib\multiprocessing
\context.py"
, line 322, in _Popen
    return Popen(process_obj)
  File"C:\Users\User\AppData\Local\Programs\Python\Python36\lib\multiprocessing
\popen_spawn_win32.py"
, line 65, in __init__
    reduction.dump(process_obj, to_child)
  File"C:\Users\User\AppData\Local\Programs\Python\Python36\lib\multiprocessing

eduction.py"
, line 60, in dump
    ForkingPickler(file, protocol).dump(obj)
AttributeError: Can't pickle local object 'test_multiprocessing.<locals>.func1'

Traceback (most recent call last):
  File"<string>", line 1, in <module>
  File"C:\Users\User\AppData\Local\Programs\Python\Python36\lib\multiprocessing
\spawn.py", line 99, in spawn_main
    new_handle = reduction.steal_handle(parent_pid, pipe_handle)
  File"C:\Users\User\AppData\Local\Programs\Python\Python36\lib\multiprocessing

eduction.py", line 87, in steal_handle
    _winapi.DUPLICATE_SAME_ACCESS | _winapi.DUPLICATE_CLOSE_SOURCE)
PermissionError: [WinError 5] Access is denied

根据Linux上测试的代码,它可以工作。这是否意味着Windowspython不能支持函数中的多处理?


您的代码是正确的。您不应该将if __name__ == '__main__':保留在函数内部。在这里阅读更多关于它的信息,为什么name=="main"

尝试如下,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from multiprocessing import Process
import time

def test_multiprocessing():
    def func1():
        print('test1')
        time.sleep(10)  
    def func2():
        print('test2')
        time.sleep(5)

    p_func1 = Process(target=func1)
    p_func2 = Process(target=func2)
    p_func1.start()
    p_func2.start()
    p_func1.join()
    p_func2.join()  
    print('done')

test_multiprocessing()


@prakash答案中的一点更正。您需要从if __name__=="__main__"内部调用函数

这里,解释得很好!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from multiprocessing import Process
import time


def func1():
    print('test1')
    time.sleep(10)

def func2():
    print('test2')
    time.sleep(5)

def test_multiprocessing():
    p_func1 = Process(target=func1)
    p_func2 = Process(target=func2)
    p_func1.start()
    p_func2.start()
    p_func1.join()
    p_func2.join()
    print('done')

if __name__=="__main__":
    test_multiprocessing()

另一种方法是可以将方法绑定到类,因为只有在模块的顶级定义函数时,函数才是可拾取的。如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from multiprocessing import Process
import time

class Foo:

    def func1(self):
        print('test1')
        time.sleep(10)

    def func2(self):
        print('test2')
        time.sleep(5)

    def test_multiprocessing(self):
        p_func1 = Process(target=self.func1)
        p_func2 = Process(target=self.func2)
        p_func1.start()
        p_func2.start()
        p_func1.join()
        p_func2.join()
        print('done')

if __name__=="__main__":
    f=Foo()
    f.test_multiprocessing()