Уведомления

Группа в Telegram: @pythonsu

#1 Май 15, 2012 14:21:19

Moroznui
От:
Зарегистрирован: 2010-10-12
Сообщения: 29
Репутация: +  0  -
Профиль   Отправить e-mail  

Многопоточность

Добрый день, уважаемые Питонисты!
В первый раз сталкиваюсь с многопоточностью в Питоне и не могу понять решение одной проблемы.

Нужно функцию do_smth() вынести в отдельные потоки, но при этом порядок элементов в новом массиве не должен поменяться.

def do_smth(a):
            .......
            sleep(20)
new = []
for obj in objs:
            foo = do_smth(obj)
            new = new.append(foo)

т.е. на выходе new=do_smth(objs) or new=do_smth(objs)

Использовать очереди? Блокировки? Как? Мб кто-нибудь покажет пример кода.
Заранее спасибо!



Офлайн

#2 Май 15, 2012 14:52:06

dehun
От: Ukraine::Kiev
Зарегистрирован: 2012-04-25
Сообщения: 26
Репутация: +  3  -
Профиль   Отправить e-mail  

Многопоточность

разбивать на части. например на пополам.

In [25]: lst = range(0, 11)

In [26]: divider = len(lst)/2

In [27]: print lst
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

In [28]: print divider
5

In [29]: part1 = lst[divider:]

In [30]: part2 = lst[:divider]

In [31]: print part1
[5, 6, 7, 8, 9, 10]

In [32]: print part2
[0, 1, 2, 3, 4]
и потом конкатенировать результаты обработки. но теоретически приросту по производительности таким образом добится не удастся если конечно в do_smth не вызывается какаянить отправка по сети или запись на диск.

Отредактировано dehun (Май 15, 2012 14:56:35)

Офлайн

#3 Май 15, 2012 15:00:18

Moroznui
От:
Зарегистрирован: 2010-10-12
Сообщения: 29
Репутация: +  0  -
Профиль   Отправить e-mail  

Многопоточность

dehum, здесь разбиение не поможет.

Есть какая-то очень долгая операция над элементом массива(в моем случае do_smth() ), мы распараллеливаем их(выносим в отдельные потоки), но в таком случае я не могу гарантировать, что функция для первого элемента отработает раньше, чем для второго.
Если для N-ого элемента функция завершится быстрее - ей нужно будет подождать всех предыдуших.
Вопрос - где поставить лок? Или в питоне есть более изящное решение?



Офлайн

#4 Май 15, 2012 15:04:01

dehun
От: Ukraine::Kiev
Зарегистрирован: 2012-04-25
Сообщения: 26
Репутация: +  3  -
Профиль   Отправить e-mail  

Многопоточность

погуглил немного - http://dispy.sourceforge.net/
выглядит похоже на то что нужно.

если же в do_smth просто какието сетевые обработки то попробуйте грин треды.
например функцию imap или starmap из eventlet.GreenPool
http://eventlet.net/doc/modules/greenpool.html#eventlet.greenpool.GreenPool

Офлайн

#5 Май 15, 2012 15:07:18

dehun
От: Ukraine::Kiev
Зарегистрирован: 2012-04-25
Сообщения: 26
Репутация: +  3  -
Профиль   Отправить e-mail  

Многопоточность

дык мы вот получили парт1 и парт2.
теперь выполняем в отдельных потоках функции обработки этих данных.
получаем парт1резалт и парт2резалт. и делаем резалт = парт1резалт + парт2резалт.
ну естествено это после того как дождались обоих потоков обработки. дожидание обоих потоков я бы реализовал через join функцию.
но по перформансу это нам ничего не даст.
так как

CPython implementation detail: Due to the Global Interpreter Lock, in CPython only one thread can execute Python code at once (even though certain performance-oriented libraries might overcome this limitation). If you want your application to make better of use of the computational resources of multi-core machines, you are advised to use multiprocessing. However, threading is still an appropriate model if you want to run multiple I/O-bound tasks simultaneously.

Отредактировано dehun (Май 15, 2012 15:07:36)

Офлайн

#6 Май 15, 2012 15:10:09

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

Многопоточность

Очень похоже, что нужна функция map из модуля multiprocessing (multiprocessing.Pool).

Для потоков есть недокументированный ThreadPool с тем же интерфейсом (обсуждение на StackOverflow)

pool = Pool(processes=4) 
results = pool.map(do_smth, objs)

Отредактировано reclosedev (Май 15, 2012 15:10:57)

Офлайн

#7 Май 15, 2012 16:21:39

fata1ex
От:
Зарегистрирован: 2009-07-11
Сообщения: 732
Репутация: +  52  -
Профиль   Отправить e-mail  

Многопоточность

Как насчет заносить результаты работы функций в словарь с правильными ключами/значениями, а потом сливать всё в список, упорядочивая результаты по ключу/значению соответственно.



Офлайн

#8 Май 15, 2012 16:27:07

dehun
От: Ukraine::Kiev
Зарегистрирован: 2012-04-25
Сообщения: 26
Репутация: +  3  -
Профиль   Отправить e-mail  

Многопоточность

только вызывать функцию там надо чуть хитрее.
у меня напрямую не получилось - погуглил - вот что нашёл
stackoverflow

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version