2016-02-14 15 views
5

Tôi đang cố gắng sử dụng concurrent.futures.ProcessPoolExecutor bằng Khóa, nhưng tôi gặp lỗi thời gian chạy. (Tôi đang làm việc trên Windows nếu có liên quan)ProcessPoolExecutor và Khóa bằng Python

Dưới đây là mã của tôi:

import multiprocessing 
from concurrent.futures import ProcessPoolExecutor 

import time 


def f(i, lock): 
    with lock: 
     print(i, 'hello') 
     time.sleep(1) 
     print(i, 'world') 


def main(): 
    lock = multiprocessing.Lock() 
    pool = ProcessPoolExecutor() 
    futures = [pool.submit(f, num, lock) for num in range(3)] 
    for future in futures: 
     future.result() 


if __name__ == '__main__': 
    main() 

Đây là lỗi tôi nhận được:

Traceback (most recent call last): 
    File "F:\WinPython-64bit-3.4.3.2\python-3.4.3.amd64\Lib\multiprocessing\queues.py", line 242, in _feed 
    obj = ForkingPickler.dumps(obj) 
    File "F:\WinPython-64bit-3.4.3.2\python-3.4.3.amd64\Lib\multiprocessing\reduction.py", line 50, in dumps 
    cls(buf, protocol).dump(obj) 
    File "F:\WinPython-64bit-3.4.3.2\python-3.4.3.amd64\Lib\multiprocessing\synchronize.py", line 102, in __getstate__ 
    context.assert_spawning(self) 
    File "F:\WinPython-64bit-3.4.3.2\python-3.4.3.amd64\Lib\multiprocessing\context.py", line 347, in assert_spawning 
    ' through inheritance' % type(obj).__name__ 
RuntimeError: Lock objects should only be shared between processes through inheritance 

Có gì lạ là nếu tôi viết cùng mã với multiprocessing.Process tất cả đều hoạt động tốt:

import multiprocessing 

import time 


def f(i, lock): 
    with lock: 
     print(i, 'hello') 
     time.sleep(1) 
     print(i, 'world') 


def main(): 
    lock = multiprocessing.Lock() 
    processes = [multiprocessing.Process(target=f, args=(i, lock)) for i in range(3)] 
    for process in processes: 
     process.start() 
    for process in processes: 
     process.join() 



if __name__ == '__main__': 
    main() 

Công việc này và tôi nhận được:

1 hello 
1 world 
0 hello 
0 world 
2 hello 
2 world 

Trả lời

3

Bạn cần phải sử dụng một Manager và sử dụng một Manager.Lock() thay vì:

import multiprocessing 
from concurrent.futures import ProcessPoolExecutor 

import time 

def f(i, lock): 
    with lock: 
     print(i, 'hello') 
     time.sleep(1) 
     print(i, 'world') 

def main(): 
    pool = ProcessPoolExecutor() 
    m = multiprocessing.Manager() 
    lock = m.Lock() 
    futures = [pool.submit(f, num, lock) for num in range(3)] 
    for future in futures: 
     future.result() 


if __name__ == '__main__': 
    main() 

Kết quả:

% python locks.py 
0 hello 
0 world 
1 hello 
1 world 
2 hello 
2 world 
Các vấn đề liên quan