Найти - Пользователи
Полная версия: [q] Twisted
Начало » Network » [q] Twisted
1 2
van-gog
Доброго времени суток!

У меня возникла проблема с Twisted.internet.threads
есть код:
…..
def getData(url):
res = getPage(url)
return

def resCallBack(data):
print data
reactor.stop()

d = threads.deferToThread(getData, ‘some site’)
d.addCallback(resCallBack)
reactor.run()
После работы этого скрипта мне выдает следующее:
<Deferred at 0xfd1878>
Но по идее должно выдать код страницы…
В чем проблема ?
ЗЫ: в гугле смотрел…
Андрей Светлов
Все правильно.
twisted.web.getPage возвращает именно deferred, который ты и видишь - это раз.
getPage не может быть вызвана из потока - только из реактора (есть хитрые возможности, но они сейчас не интересны). deferToThread делали не для твоего случая. Это два.
van-gog
Андрей Светлов
Все правильно.
twisted.web.getPage возвращает именно deferred, который ты и видишь - это раз.
getPage не может быть вызвана из потока - только из реактора (есть хитрые возможности, но они сейчас не интересны). deferToThread делали не для твоего случая. Это два.
А для каких целей делали deferToThread?
И каким образом это можно обойти, если не секрет?
Андрей Светлов
deferToThread нужен для выполнения долгих операций, не знающих о реакторе, в пуле потоков (в отдельном потоке, для простоты понимания). Примеры таких операций - “длинные” обращения к базе данных, выполнение долгих вычислений.

У тебя другой случай. Нужно делать
def onPage(page):
print page

def stopReactor(arg):
reactor.stop()

d = getPage('some site')
d.addCallback(onPage).addCallback(stopReactor)
reactor.run()

Остановка реактора после получения странички - только для теста, конечно же. Реактор должен работять всю жизнь приложения.
van-gog
Мне как раз нужно чтобы страничка скачивалась в потоке, и из потока вызывался колбек.
В моем случае сраничка содержит ооочень много записей, и таких страничек за определенный промежуток времени нужно обработать несколько.
На скачку одной страницы уходит приблизительно 6-10 секунд.
Андрей Светлов
Вариант 2
.....
def getData(url):
page = urllib2.urlopen(url)
body = page.read()
# process page
ret = process(body)
return [url, res]

def resCallBack(data):
print data[1]
reactor.stop()

d = threads.deferToThread(getData, 'some site')
d.addCallback(resCallBack)
reactor.run()
Третий вариант - переписать twisted.web.client.HTTPClientFactory, чтобы вытягивала и обрабатывала страничку по частям. Это - сложнее.
van-gog
Спасибо за ответ :)

Теперь возник другой вопрос:
как запустить одновременно 10 потоков, каждый из которых после выполнения добавляет в список задач новую задачу, и она уже, если количество потоков < 10, тоже запускается в отдельном потоке.

Я сделал так:

def run():
if len(threads) < 10:
if len(tasks) == 0:
reactor.stop()
pass
else:
if len(tasks) > 0:
function, params, callback = tasks.pop(0)
threads.deferToThread(function, params).addCallback(callback)
reactor.run()
threads.append(params)
sleep(.1) #чтоб не слишком загружать процессор

Но этот кусок кода работает не совсем правильно :(
Первое задание выполняется, а остальные - нет :(
Помогите пожалуйста.
ЗЫ: гугл ответа не дал :(
Андрей Светлов
:)
Ты должен просто ничего не делать.
реактор уже содержит пул потоков. С максимальным размером именно в 10 штук.
Поэтому просто бомби threads.deferToThread сколько хочешь раз. Больше десяти одновременно выполняться не будет.
sleep - тоже не нужен. У тебя реактор должен все время крутиться.

Код инициализации пула в twisted.internet.base:_initThreadPool

сам пул в twisted.python.threadpool
van-gog
Андрей Светлов
:)
Ты должен просто ничего не делать.
реактор уже содержит пул потоков. С максимальным размером именно в 10 штук.
Поэтому просто бомби threads.deferToThread сколько хочешь раз. Больше десяти одновременно выполняться не будет.
sleep - тоже не нужен. У тебя реактор должен все время крутиться.

Код инициализации пула в twisted.internet.base:_initThreadPool

сам пул в twisted.python.threadpool
Спасибо, все заработало :)
van-gog
Здравствуйте еще раз :)
Теперь возник такой вопрос: как сделать чтоб ссылки, которые я передаю в threads.daferToThread скачивались через равное количество времени, н-р 1с. (ато сервер сильно грузит)
Зарание спасибо
ЗЫ: пробовал sleep - не реагирует
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