Ошибка при запуске нескольких процессов
Начал разбираться с потоками. Для этого написал следующий код:
def sqrt_pandas(x,q):
q.put(math.sqrt(x))
if __name__ == '__main__':
n_proc = multiprocessing.cpu_count()
print(n_proc)
process = []
lst_proc = []
number = 0
lst = [random.randint(1, 10000) for i in range(0, 1000)]
start_time = time.time()
for i in lst:
if number<n_proc:
q = multiprocessing.Queue()
p = multiprocessing.Process(target=sqrt_pandas, args=(i, q))
process.append(p)
p.start()
print(q.get())
else:
for p in process:
p.join()
process = []
number = 0
print(time.time()-start_time)
Но получаю следующую ошибку:
Traceback (most recent call last):
File "/tmp/pycharm_project_880/test.py", line 27, in <module>
p.start()
File "/usr/lib/python3.8/multiprocessing/process.py", line 121, in start
self._popen = self._Popen(self)
File "/usr/lib/python3.8/multiprocessing/context.py", line 224, in _Popen
return _default_context.get_context().Process._Popen(process_obj)
File "/usr/lib/python3.8/multiprocessing/context.py", line 277, in _Popen
return Popen(process_obj)
File "/usr/lib/python3.8/multiprocessing/popen_fork.py", line 19, in __init__
self._launch(process_obj)
File "/usr/lib/python3.8/multiprocessing/popen_fork.py", line 69, in _launch
child_r, parent_w = os.pipe()
OSError: [Errno 24] Too many open files
В чем я ошибся при написании данного кода.
Ответы (1 шт):
Так, ну с сутью ошибки вы сами разобрались - счётчик number у вас не увеличивался, join не происходил и процессы в системе в итоге заканчивались. Но главное в вашем коде - у вас нет на самом деле никакой многопоточности, процессы выполняются последовательно! Это происходит из-за вызова q.get() - он ждёт результата. Поэтому следующий процесс у вас стартует не раньше, чем заканчивается предыдущий. Рекомендую вам воспользоваться классом multiprocessing.Pool, с ним ваш код будет гораздо короче, проще, и, что главное, эффективнее:
import multiprocessing
import math
import time
def sqrt_pandas(x):
return math.sqrt(x)
if __name__ == '__main__':
n_proc = multiprocessing.cpu_count()
lst = [random.randint(1, 10000) for i in range(0, 1000)]
result = []
start_time = time.time()
with multiprocessing.Pool(n_proc) as pool:
for res in pool.map(sqrt_pandas, lst):
result.append(res)
print(time.time()-start_time)
Печать я убрал, чтобы не забивала экран, но даже с печатью этот код выполняется за доли секунды.
Как видите, 12 строчек кода работы с процессами превратились в 3 строки, и при этом всё просто и понятно.