#python #python-multithreading
#python #python-многопоточность
Вопрос:
Привет, я действительно новичок в обработке потоков, и это приводит меня в замешательство, как я могу запустить этот код параллельно?
def search_posts(page):
page_url = f'https://jsonplaceholder.typicode.com/posts/{page}'
req = requests.get(page_url)
res = req.json()
title = res['title']
return title
page = 1
while True:
with ThreadPoolExecutor() as executer:
t = executer.submit(search_posts, page)
title = t.result()
print(title)
if page == 20:
break
page = 1
Еще один вопрос: нужно ли мне изучать операционные системы, чтобы понять, как работает потоковая передача?
Комментарии:
1. Большое спасибо за продолжение, конечно, я обязательно проверю это
Ответ №1:
Проблема здесь в том, что вы создаете новый ThreadPoolExecutor
для каждой страницы. Чтобы выполнять что-то параллельно, создайте только один ThreadPoolExecutor
и используйте его map
метод:
import concurrent.futures as cf
import requests
def search_posts(page):
page_url = f'https://jsonplaceholder.typicode.com/posts/{page}'
res = requests.get(page_url).json()
return res['title']
if __name__ == '__main__':
with cf.ThreadPoolExecutor() as ex:
results = ex.map(search_posts, range(1, 21))
for r in results:
print(r)
Обратите внимание, что использование if __name__ == '__main__'
оболочки является хорошей привычкой для повышения переносимости вашего кода.
При использовании потоков следует помнить одну вещь; Если вы используете CPython (реализацию Python из python.org
, которая является наиболее распространенной), потоки фактически не выполняются параллельно.
Чтобы упростить управление памятью, только один поток одновременно может выполнять байт-код Python в CPython. Это обеспечивается глобальной блокировкой интерпретатора («GIL») в CPython.
Хорошей новостью является то, что использование requests
для получения веб-страницы будет тратить большую часть своего времени на сетевой ввод-вывод. И вообще, GIL освобождается во время ввода-вывода.
Но если вы выполняете вычисления в своих рабочих функциях (т. Е. выполняете байт-код Python), вам следует использовать ProcessPoolExecutor
вместо этого.
Если вы используете ProcessPoolExecutor
и работаете в ms-Windows, то использование if __name__ == '__main__'
оболочки обязательно, потому что в этом случае Python должен быть способен работать с import
вашей основной программой без побочных эффектов.