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