Форум сайта python.su
Доброго времени суток!
У меня возникла проблема с 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>
Отредактировано (Май 7, 2008 17:27:37)
Офлайн
Все правильно.
twisted.web.getPage возвращает именно deferred, который ты и видишь - это раз.
getPage не может быть вызвана из потока - только из реактора (есть хитрые возможности, но они сейчас не интересны). deferToThread делали не для твоего случая. Это два.
Офлайн
Андрей СветловА для каких целей делали deferToThread?
Все правильно.
twisted.web.getPage возвращает именно deferred, который ты и видишь - это раз.
getPage не может быть вызвана из потока - только из реактора (есть хитрые возможности, но они сейчас не интересны). deferToThread делали не для твоего случая. Это два.
Отредактировано (Апрель 25, 2008 17:04:19)
Офлайн
deferToThread нужен для выполнения долгих операций, не знающих о реакторе, в пуле потоков (в отдельном потоке, для простоты понимания). Примеры таких операций - “длинные” обращения к базе данных, выполнение долгих вычислений.
У тебя другой случай. Нужно делать
def onPage(page):
print page
def stopReactor(arg):
reactor.stop()
d = getPage('some site')
d.addCallback(onPage).addCallback(stopReactor)
reactor.run()
Остановка реактора после получения странички - только для теста, конечно же. Реактор должен работять всю жизнь приложения.
Офлайн
Мне как раз нужно чтобы страничка скачивалась в потоке, и из потока вызывался колбек.
В моем случае сраничка содержит ооочень много записей, и таких страничек за определенный промежуток времени нужно обработать несколько.
На скачку одной страницы уходит приблизительно 6-10 секунд.
Отредактировано (Апрель 25, 2008 18:52:17)
Офлайн
Вариант 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()
Офлайн
Спасибо за ответ :)
Теперь возник другой вопрос:
как запустить одновременно 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) #чтоб не слишком загружать процессор
Но этот кусок кода работает не совсем правильно :(
Первое задание выполняется, а остальные - нет :(
Помогите пожалуйста.
ЗЫ: гугл ответа не дал :(
Отредактировано (Май 7, 2008 17:27:06)
Офлайн
:)
Ты должен просто ничего не делать.
реактор уже содержит пул потоков. С максимальным размером именно в 10 штук.
Поэтому просто бомби threads.deferToThread сколько хочешь раз. Больше десяти одновременно выполняться не будет.
sleep - тоже не нужен. У тебя реактор должен все время крутиться.
Код инициализации пула в twisted.internet.base:_initThreadPool
сам пул в twisted.python.threadpool
Офлайн
Андрей СветловСпасибо, все заработало :)
:)
Ты должен просто ничего не делать.
реактор уже содержит пул потоков. С максимальным размером именно в 10 штук.
Поэтому просто бомби threads.deferToThread сколько хочешь раз. Больше десяти одновременно выполняться не будет.
sleep - тоже не нужен. У тебя реактор должен все время крутиться.
Код инициализации пула в twisted.internet.base:_initThreadPool
сам пул в twisted.python.threadpool
Офлайн
Здравствуйте еще раз :)
Теперь возник такой вопрос: как сделать чтоб ссылки, которые я передаю в threads.daferToThread скачивались через равное количество времени, н-р 1с. (ато сервер сильно грузит)
Зарание спасибо
ЗЫ: пробовал sleep - не реагирует
Офлайн