Статьи

Базовый Python: сравнение одиночного и многопоточного исполнения

Это отрывок из недавней книги Уэсли Чуна « Базовое программирование приложений на Python».

 

Многопоточное программирование


> С Python вы можете запустить поток, но вы не можете его остановить
.
> Извините. Вам придется подождать, пока он не достигнет конца исполнения .
Итак, точно так же, как [comp.lang.python], тогда ?

— Клифф Уэллс, Стив Холден (и Тимоти Делани), февраль 2002 г.

 

4.1 Введение / Мотивация 157

В этом разделе мы рассмотрим различные способы достижения большего параллелизма в вашем коде. Мы начнем с разграничения между процессами и потоками в первых нескольких разделах этой главы. Затем мы введем понятие многопоточного программирования и представим некоторые возможности многопоточного программирования, найденные в Python. (Те из вас, кто уже знаком с многопоточным программированием, могут сразу перейти к разделу 4.3.5.) В заключительных разделах этой главы представлены некоторые примеры использования модулей потоков и очереди для выполнения многопоточного программирования на Python.

[…]

 

4.6   Сравнение одиночного и многопоточного исполнения

Сценарий mtfacfib.py , представленный в примере 4-8, сравнивает выполнение рекурсивных функций Фибоначчи, факториала и суммирования. Этот скрипт запускает все три функции в однопоточном режиме. Затем он выполняет ту же задачу, используя потоки, чтобы проиллюстрировать одно из преимуществ наличия потоковой среды.

Пример 4-8 Фибоначчи, Факториал, Суммирование ( mtfacfib.py )

В этом MT приложении мы выполняем три отдельные рекурсивные функции-первых , в
виде

однопоточных моды, а затем альтернатива с несколькими потоками
.

#!/usr/bin/env python

from myThread import MyThread
from time import ctime, sleep

def fib(x):
sleep(0.005)
if x < 2: return 1
return (fib(x-2) + fib(x-1))

def fac(x):
sleep(0.1)
if x < 2: return 1
return (x * fac(x-1))

def sum(x):
sleep(0.1)
if x < 2: return 1
return (x + sum(x-1))

funcs = [fib, fac, sum]
n = 12

def main():
nfuncs = range(len(funcs))

print '*** SINGLE THREAD'
for i in nfuncs:
print 'starting', funcs[i].__name__, 'at:', \
ctime()
print funcs[i](n)
print funcs[i].__name__, 'finished at:', \
ctime()

print '\n*** MULTIPLE THREADS'
threads = []
for i in nfuncs:
t = MyThread(funcs[i], (n,), 
funcs[i].__name__)
threads.append(t)

for i in nfuncs:
threads[i].start()

for i in nfuncs:
threads[i].join()
print threads[i].getResult()

print 'all DONE'

if __name__ == '__main__':
main()

Работа в однопоточном режиме просто включает вызов функций по одному и отображение соответствующих результатов сразу после вызова функции.

При работе в многопоточном режиме мы не показываем результат сразу. Поскольку мы хотим, чтобы наш класс MyThread был как можно более общим (возможность выполнять вызовы, которые производят и не производят вывод), мы ждем до конца вызова метода getResult (), чтобы, наконец, показать вам возвращаемые значения каждого вызова функции ,

Поскольку эти функции выполняются так быстро (ну, может быть, за исключением функции Фибоначчи), вы заметите, что нам пришлось добавить вызовы sleep () для каждой функции, чтобы замедлить процесс, чтобы мы могли видеть, как многопоточность может улучшить производительность, если это действительно так реальная работа имела различное время выполнения — вы, конечно, не дополнили бы свою работу вызовами sleep () . Во всяком случае, вот вывод:



$ mtfacfib.py

*** ЕДИНСТВЕННАЯ
РЕЗЬБА,

начиная с: ср. 16 ноября, 18:52:20 2011 г.
233
фиба

закончилась в: ср. 16 ноября, 18:52:24 2011 год,

начиная с: ср. 16 ноября, 18:52:24 2011

479001600

Фак закончен в: ср 16 ноя 18:52:26 2011

начальная сумма в: ср 16 ноя 18:52:26 2011

8

сумма закончилась в: ср 16 ноя 18:52:27 2011

*** НЕСКОЛЬКО НИТЕЙ,

начиная фиб в: ср 16 ноября, 18:52:27 Начало 2011 года

в: ср. 16 ноября 18:52:27 Начало в 2011 году

в: ср. 16 ноября, 18:52:27 Окончание 2011 года

в: ср. 16 ноября, 18:52:28
Сумма 2011 года
завершена в : Ср 16 ноя 18:52:28 2011

фиб закончен в: ср 16 ноя 18:52:31 2011

233

47900160
78

все
СДЕЛАНО

Полное оглавление главы включает в себя:

  • Введение / Мотивация
  • Темы и процессы
  • Темы и Питон
  • Нить модуль
  • Резьб модуль
  • Сравнение одиночного и многопоточного исполнения
  • Многопоточность на практике
  • Проблема производителя-потребителя и модуль очереди / очереди
  • Альтернативные соображения для потоков
  • Связанные модули

Книга доступна для покупки через Amazon.com , или вы можете прочитать ее онлайн на SafarBooksOnline.com