Найти - Пользователи
Полная версия: thread-safe generator
Начало » Python для новичков » thread-safe generator
1 2
CEMEH
Есть некоторая ф-йия
def func(vals):
for val in vals:
fo_something(val)
где в качестве vals передается генератор.
Понадобилось сделать вызов этой ф-ции многопоточным. Т.е. что-то типа:
for x in range(0,n):
thread = threading.Thread(target=func, args=[vals])
thread.start()
Есть ли готовые решения thread-safe оберток над генератором, чтоб не изменять func ?
Т.е. в идеале хотелось бы:
tsVals = ThreadSafeGeneratorWrapper(vals)
for x in range(0,n):
thread = threading.Thread(target=func, args=[tsVals])
thread.start()
Андрей Светлов
А что означает thread safe для генератора?
CEMEH
Андрей Светлов
А что означает thread safe для генератора?
Означет, что данные беруться несколькими потокамии при этом не возникает конфликтов доступа.
Вот эта ф-ция работает одновременно в нескольких потоках:
def func(vals):
for val in vals:
fo_something(val)
на каждой итерации из генератора выбирается очередное значение.
Т.е. получается очередь данных, которые разбираются потоками.
Но очередь не сформирована изначально, а данные генерируются по ходу обращения.

Пока собираюсь заюзать такой враппер:
class LockedIterator(object):
def __init__(self, it):
self.lock = threading.Lock()
self.it = it.__iter__()

def __iter__(self): return self

def next(self):
self.lock.acquire()
try:
return self.it.next()
finally:
self.lock.release()
Андрей Светлов
Напряженно думаю. А где конфликт доступа?
CEMEH
Андрей Светлов
Напряженно думаю. А где конфликт доступа?
В самом генераторе, т.к. генерация очередного значения - не атомарная операция.
agalen
CEMEH
Т.е. получается очередь данных, которые разбираются потоками.
Здесь как раз пригодится очередь (см. модуль Queue).
CEMEH
Не годится по двум причинам:
1) как понимаю в очередь данные заносятся не зависимо от их выборки, а у меня генератор.
2) на самом деле у меня используется 2 независимых генератора

ну и ф-цию придется переписывать на использование очереди.
CEMEH
В принципе LockedIterator, который привел выше, полностью подходит. Просто, думал, что такой велосипед уже есть в стандартных библиотеках.
Андрей Светлов
Проблему понял. В стандартной библиотеке такого нет и не будет.
Вообще не уверен, что разделение генератора между потоками — хорошая идея. Как по мне — настоящий antipattern получается.
Впрочем, вам — виднее.
denz
В 2.6.5+ есть multiprocessing. Не уверен насколько подойдет сам модуль, поскольку это вообще не threading а скорее альтернатива тредингу с ограничениями, но там есть Proxy объекты. И гдето в сети гуляла статья с примерами многозадачных итераторов сделанных на базе этих Proxy.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB