Документация по Python

Глобальная блокировка интерпретатора (GIL)

В: Документация по Python

Multiprocessing.Pool

На вопрос, как использовать потоки в Python, ответ прост: «Не используйте вместо этого процессы». Модуль многопроцессорной обработки позволяет создавать процессы с синтаксисом, аналогичным синтаксису создания потоков, но я предпочитаю использовать их удобный объект Pool.

Используя код , который Дэвид Бизли первым используется , чтобы показать опасность нитей против GIL , мы перепишем его с помощью multiprocessing.Pool :

Код Дэвида Бизли, который показал проблемы с GIL-потоками

 from threading import Thread
import time
def countdown(n):
    while n > 0:
        n -= 1

COUNT = 10000000

t1 = Thread(target=countdown,args=(COUNT/2,))
t2 = Thread(target=countdown,args=(COUNT/2,))
start = time.time()
t1.start();t2.start()
t1.join();t2.join()
end = time.time()
print end-start

 


Переписано с использованием мультипроцессинга.

Вместо создания потоков это создает новые процессы. Поскольку каждый процесс имеет свой собственный интерпретатор, коллизии GIL отсутствуют. multiprocessing.Pool откроет столько процессов, сколько имеется ядер на машине, хотя в приведенном выше примере потребуется только два. В реальном сценарии вы хотите, чтобы ваш список был как минимум такой же длины, как и процессоры на вашей машине. Пул будет запускать функцию, которую вы скажете ему запускать с каждым аргументом, вплоть до числа процессов, которые он создает. Когда функция завершится, все остальные функции в списке будут запущены в этом процессе.

Я обнаружил , что, даже используя with заявлением, если вы не близко и присоединиться к пулу, процессы продолжают существовать. Чтобы очистить ресурсы, я всегда закрываюсь и присоединяюсь к своим бассейнам.

Cython Nogil:

Cython является альтернативным интерпретатором Python. Он использует GIL, но позволяет отключить его. Смотрите их документации

В качестве примера, используя код , который Дэвид Бизли первым используется , чтобы показать опасность нитей против GIL , мы перепишем его с помощью nogil:

Код Дэвида Бизли, который показал проблемы с GIL-потоками

 from threading import Thread
import time
def countdown(n):
    while n > 0:
        n -= 1

COUNT = 10000000

t1 = Thread(target=countdown,args=(COUNT/2,))
t2 = Thread(target=countdown,args=(COUNT/2,))
start = time.time()
t1.start();t2.start()
t1.join();t2.join()
end = time.time()
print end-start

 

Переписано с использованием nogil (ТОЛЬКО РАБОТАЕТ НА ЦИФОНЕ):

 from threading import Thread
import time
def countdown(n):
    while n > 0:
        n -= 1

COUNT = 10000000

with nogil:
    t1 = Thread(target=countdown,args=(COUNT/2,))
    t2 = Thread(target=countdown,args=(COUNT/2,))
    start = time.time()
    t1.start();t2.start()
    t1.join();t2.join()

end = time.time()
print end-start

 

Это так просто, если вы используете Cython. Обратите внимание, что в документации сказано, что вы должны быть уверены, что не меняете объекты Python:

Код в теле оператора не должен каким-либо образом манипулировать объектами Python и не должен вызывать ничего, что манипулирует объектами Python без предварительного повторного получения GIL. Cython в настоящее время не проверяет это.

Еще от кодкамп
Замечательно! Вы успешно подписались.
Добро пожаловать обратно! Вы успешно вошли
Вы успешно подписались на кодкамп.
Срок действия вашей ссылки истек.
Ура! Проверьте свою электронную почту на наличие волшебной ссылки для входа.
Успех! Ваша платежная информация обновлена.
Ваша платежная информация не была обновлена.