简体   繁体   English

使用 concurrent.futures 的多线程/多处理解决方案

[英]Multithreading / Multiprocessing solution using concurrent.futures

Hi I'm referencing the following question because it's similar to what I'm trying to achieve, however, I'm getting an error that I can't seem to figure out so looking for some help嗨,我引用了以下问题,因为它与我想要实现的目标相似,但是,我遇到了一个我似乎无法弄清楚的错误,因此寻求一些帮助

Combining multithreading and multiprocessing with concurrent.futures 将多线程和多处理与 concurrent.futures 相结合

Here's my test code:这是我的测试代码:

from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
import numpy as np
from os import cpu_count
from functools import partial

num_list = range(0,1000)
  
def test(x):
    x**2
             
def multithread(f, lst):
    print('Thread running')
    with ThreadPoolExecutor() as thread_executor:
        thread_executor.map(f, lst)

def multiprocesser(lst, f, n_processors=cpu_count()//2):
    chunks = np.array_split(lst, n_processors)
    with ProcessPoolExecutor(max_workers=n_processors) as mp_executor:
        mp_executor.map(partial(multithread, f), chunks)

if __name__ == '__main__':
    multiprocesser(num_list, test)
Process SpawnProcess-31:
Traceback (most recent call last):
  File "C:\Users\Test_user\Anaconda3\envs\test_env\lib\multiprocessing\process.py", line 315, in _bootstrap
    self.run()
  File "C:\Users\Test_user\Anaconda3\envs\test_env\lib\multiprocessing\process.py", line 108, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\Test_user\Anaconda3\envs\test_env\lib\concurrent\futures\process.py", line 237, in _process_worker
    call_item = call_queue.get(block=True)
  File "C:\Users\Test_user\Anaconda3\envs\test_env\lib\multiprocessing\queues.py", line 122, in get
    return _ForkingPickler.loads(res)
AttributeError: Can't get attribute 'multithread' on <module '__main__' (built-in)>
Process SpawnProcess-32:
Traceback (most recent call last):
  File "C:\Users\Test_user\Anaconda3\envs\test_env\lib\multiprocessing\process.py", line 315, in _bootstrap
    self.run()
  File "C:\Users\Test_user\Anaconda3\envs\test_env\lib\multiprocessing\process.py", line 108, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\Test_user\Anaconda3\envs\test_env\lib\concurrent\futures\process.py", line 237, in _process_worker
    call_item = call_queue.get(block=True)
  File "C:\Users\Test_user\Anaconda3\envs\test_env\lib\multiprocessing\queues.py", line 122, in get
    return _ForkingPickler.loads(res)
AttributeError: Can't get attribute 'multithread' on <module '__main__' (built-in)>

So I didn't specify number of threads (don't see a reason to for the threadpool executor).所以我没有指定线程数(看不到线程池执行器的理由)。 Having trouble understanding what the error actually means and how I can fix it.无法理解错误的实际含义以及如何修复它。 Any help would be appreciated.任何帮助,将不胜感激。

The error probably stems from the fact that multithread() is being called incorrectly.该错误可能源于未正确调用 multithread() 的事实。

Try this:尝试这个:

from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
import numpy as np
from os import cpu_count
from functools import partial

num_list = range(0,1000)

def test(x):
    x**2
               
def multithread(f, lst):
    print('Thread running')
    with ThreadPoolExecutor() as thread_executor:
        thread_executor.map(f, lst)

def multiprocesser(lst, f, n_processors=cpu_count()//2):
    chunks = np.array_split(lst, n_processors)
    with ProcessPoolExecutor(max_workers=n_processors) as mp_executor:
        mp_executor.map(partial(multithread, f), chunks)

if __name__ == '__main__':
    multiprocesser(num_list, test)

Missing if __name__ == '__main__'缺少if __name__ == '__main__'

if __name__ == '__main__':
    multiprocesser(num_list, test)

Unintended recursion意外递归

When you don't block out the call to multiprocessor() , you have recursion when the subprocess runs the python script.当您不阻止对multiprocessor()的调用时,当子进程运行 python 脚本时,您将进行递归。

Safe importing of main module安全导入主模块

The following is an example of the same type of problem from the multiprocessing docs:以下是多处理文档中相同类型问题的示例:

https://docs.python.org/3/library/multiprocessing.html?highlight=multiprocess#the-spawn-and-forkserver-start-methods https://docs.python.org/3/library/multiprocessing.html?highlight=multiprocess#the-spawn-and-forkserver-start-

Make sure that the main module can be safely imported by a new Python interpreter without causing unintended side effects (such a starting a new process).确保新的 Python 解释器可以安全地导入主模块,而不会导致意外的副作用(例如启动新进程)。

For example, using the spawn or forkserver start method running the following module would fail with a RuntimeError :例如,使用 spawn 或 forkserver 启动方法运行以下模块将失败并出现RuntimeError

 multiprocessing import Process def foo(): print('hello') p = Process(target=foo) p.start()

Instead one should protect the “entry point” of the program by using if __name__ == '__main__': as follows:相反,应该使用if __name__ == '__main__':来保护程序的“入口点”,如下所示:

 from multiprocessing import Process, freeze_support, set_start_method def foo(): print('hello') if __name__ == '__main__': freeze_support() set_start_method('spawn') p = Process(target=foo) p.start() ```

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM