Форум сайта python.su
0
Добрый день, уважаемые Питонисты!
В первый раз сталкиваюсь с многопоточностью в Питоне и не могу понять решение одной проблемы.
Нужно функцию do_smth() вынести в отдельные потоки, но при этом порядок элементов в новом массиве не должен поменяться.
def do_smth(a): ....... sleep(20) new = [] for obj in objs: foo = do_smth(obj) new = new.append(foo)
Офлайн
3
разбивать на части. например на пополам.
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]
Отредактировано dehun (Май 15, 2012 14:56:35)
Офлайн
0
dehum, здесь разбиение не поможет.
Есть какая-то очень долгая операция над элементом массива(в моем случае do_smth() ), мы распараллеливаем их(выносим в отдельные потоки), но в таком случае я не могу гарантировать, что функция для первого элемента отработает раньше, чем для второго.
Если для N-ого элемента функция завершится быстрее - ей нужно будет подождать всех предыдуших.
Вопрос - где поставить лок? Или в питоне есть более изящное решение?
Офлайн
3
погуглил немного - http://dispy.sourceforge.net/
выглядит похоже на то что нужно.
если же в do_smth просто какието сетевые обработки то попробуйте грин треды.
например функцию imap или starmap из eventlet.GreenPool
http://eventlet.net/doc/modules/greenpool.html#eventlet.greenpool.GreenPool
Офлайн
3
дык мы вот получили парт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)
Офлайн
173
Очень похоже, что нужна функция map из модуля multiprocessing (multiprocessing.Pool).
Для потоков есть недокументированный ThreadPool с тем же интерфейсом (обсуждение на StackOverflow)
pool = Pool(processes=4) results = pool.map(do_smth, objs)
Отредактировано reclosedev (Май 15, 2012 15:10:57)
Офлайн
52
Как насчет заносить результаты работы функций в словарь с правильными ключами/значениями, а потом сливать всё в список, упорядочивая результаты по ключу/значению соответственно.
Офлайн
3
только вызывать функцию там надо чуть хитрее.
у меня напрямую не получилось - погуглил - вот что нашёл
stackoverflow
Офлайн