Уведомления

Группа в Telegram: @pythonsu

#1 Окт. 24, 2013 06:42:52

plusplus
От:
Зарегистрирован: 2009-01-05
Сообщения: 418
Репутация: +  15  -
Профиль   Отправить e-mail  

threadpool велосипед с помощью корутинов.

В своё время понравилась эта реализация threadpool-а

Довольно много раз приходилось её использовать и за это время было выявлено одно неудобство:
в worker нельзя писать не thread-safe код, а иногда бывает надо, например, сделать какой-то запрос к базе данных. Приходилось ставить локеры. А недавно, прочитал про корутины и увидел инлайн колбэки в twisted и подумалось: “А что если, что подобное организовать и здесь?” То есть worker передает функцию, которую нужно выполнить, в основной поток, а затем результат её выполнения возвращается обратно в worker:

def worker(arg):
    do_something_thread_safe()
    def do_something_not_thread_safe():
        pass
    result = yield do_something_not_thread_safe
    do_something_thread_safe(result)
    
Собственно, вопрос, нужно ли всё это? Есть в этом какое-то преимущество, по сравнению с локерами?



Офлайн

#2 Окт. 24, 2013 11:35:31

o7412369815963
От:
Зарегистрирован: 2009-06-17
Сообщения: 1986
Репутация: +  32  -
Профиль   Отправить e-mail  

threadpool велосипед с помощью корутинов.

plusplus
thread-safe код, а иногда бывает надо, например, сделать какой-то запрос к базе данных.
Можно использовать thread-safe либы для БД, они наверно чаще такие и есть.

plusplus
То есть worker передает функцию, которую нужно выполнить, в основной поток, а затем результат её выполнения возвращается обратно в worker:
Идея интересная, но я думаю “игра не стоит свеч”. Для передачи в другой поток, yield не поможет, нужно делать “акторы” с передачей данных через какие-нибудь queue.

plusplus
прочитал про корутины
По идее, то что на yield - это генераторы, корутины - это на гринлетах. Выполняются в одном потоке, и (все) операции - неблокирующие.

Офлайн

#3 Окт. 24, 2013 12:22:13

plusplus
От:
Зарегистрирован: 2009-01-05
Сообщения: 418
Репутация: +  15  -
Профиль   Отправить e-mail  

threadpool велосипед с помощью корутинов.

o7412369815963
Идея интересная, но я думаю “игра не стоит свеч”. Для передачи в другой поток, yield не поможет, нужно делать “акторы” с передачей данных через какие-нибудь queue.

Ну вот по ссылке что я дал как раз так и организовано это. Результаты складываются в queue из которой потом yield-ятся. Я же хочу чутка модернизировать этот код. По сути вопрос состоит в следующем: стоит ли вместо этого кода:
def worker(arg):
    do_something_thread_safe()
    # self.__mutex - это threading.Lock
    with self.__mutex:
        result = do_something_not_thread_safe():
    do_something_thread_safe(result)

поправить данный модуль так, чтобы можно было писать так как я написал в первом посте?



Офлайн

#4 Окт. 29, 2013 19:32:25

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

threadpool велосипед с помощью корутинов.

Знаю случай, когда только локами не обойтись - это GUI библиотеки. Там большая часть обновлений GUI элементов должна проходить в основном потоке.

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

Я с корутинами делал похожее, только наоборот, то что yield'илось выполнялось в отдельном потоке/процессе/гринлете (http://python.su/forum/topic/21180/).

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version