Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 20, 2011 12:22:31

Игнат
От:
Зарегистрирован: 2010-10-02
Сообщения: 224
Репутация: +  0  -
Профиль   Отправить e-mail  

как прервать работу потоков в concurrent.futures?

здравствуйте

запускать потоки научился, но не могу понять как их теперь остановить

запускаю так:

        self.executor = ThreadPoolExecutor(max_workers=self.threads)
self.pending = set()

for proxy in proxies:
future = self.executor.submit(self.worker, proxy)
future.add_done_callback(self.process_result)
self.log('проверяем ' + proxy)
self.pending.add(future)
self.app.processEvents()
делал в классе флаг - self.stopCheck, который становился True при нажатии кнопки в UI
затем вставлял проверку на этот флаг в self.worker, self.process_result, в слот, который вызывается из self.process_result для обновления UI
пробовал обнулять self.pending

ничего не помогает, всё работает как работало
подскажите, что нужно сделать, чтобы корректно убить все созданные потоки и не плодить новых?



Офлайн

#2 Янв. 20, 2011 15:25:32

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

как прервать работу потоков в concurrent.futures?

Вот именно флаг и должен помогать. Нужно остановится - проверили это в self.worker и завершились.
Фраза вроде: “я все перепробовал, но ничего не подошло” не очень информативна.



Офлайн

#3 Янв. 20, 2011 15:53:11

Игнат
От:
Зарегистрирован: 2010-10-02
Сообщения: 224
Репутация: +  0  -
Профиль   Отправить e-mail  

как прервать работу потоков в concurrent.futures?

пробовал так:

    def process_result(self, future):

self.pending.discard(future)

if self.stopCheck:
future.cancel() # или просто делал здесь ретурн

if future.cancelled():
return

res, proxy = future.result()

self.emit(QtCore.SIGNAL("threadDone"), [res, proxy]) # и в threadDone пробовал тоже ставить ретурн
и так:
    def worker(self, proxy):
''' thread body '''

self.emit(QtCore.SIGNAL("threadStarted"))

if self.stopCheck: # тоже бестолку
return [5, proxy]

if ':' not in proxy:
return [3, proxy]

try:
hnd = http.client.HTTPConnection(proxy, timeout=1)
hnd.request('GET', self.checkUrl, '', {'Content-Type': 'application/x-www-form-urlencoded'})
body = hnd.getresponse().read().decode(self.charsetToCheck)

return [1, proxy] if self.checkText in body else [0, proxy]
except:
return [4, proxy]
а это метод, повешанный на кнопку СТОП
    def stop(self):
self.stopCheck = True
self.log('останавливаем проверку')



Офлайн

#4 Янв. 20, 2011 17:00:14

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

как прервать работу потоков в concurrent.futures?

Стоп-стоп.
У вас 100 заданий. 35 закончились, 10 еще работают, 45 ждут свободных потоков в executor.
Что должна сделать остановка?



Офлайн

#5 Янв. 20, 2011 21:40:21

Игнат
От:
Зарегистрирован: 2010-10-02
Сообщения: 224
Репутация: +  0  -
Профиль   Отправить e-mail  

как прервать работу потоков в concurrent.futures?

прервать оставшихся. чтобы они, получив свободные потоки - не чекали прокси, не делали свою работу, а просто завершались тихо



Офлайн

#6 Янв. 22, 2011 15:34:33

Игнат
От:
Зарегистрирован: 2010-10-02
Сообщения: 224
Репутация: +  0  -
Профиль   Отправить e-mail  

как прервать работу потоков в concurrent.futures?

кто-нибудь знает как это сделать?



Офлайн

#7 Янв. 22, 2011 16:42:20

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

как прервать работу потоков в concurrent.futures?

Послушайте. У вас же есть self.pending.
Сделайте для них .cancel
Или я чего-то не понимаю?



Офлайн

#8 Янв. 26, 2011 21:49:14

Игнат
От:
Зарегистрирован: 2010-10-02
Сообщения: 224
Репутация: +  0  -
Профиль   Отправить e-mail  

как прервать работу потоков в concurrent.futures?

так я же делал:

    def process_result(self, future):

self.pending.discard(future)

if self.stopCheck:
future.cancel() # или просто делал здесь ретурн

if future.cancelled():
return
сам pending - list



Отредактировано (Янв. 26, 2011 21:49:41)

Офлайн

#9 Янв. 26, 2011 22:00:18

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

как прервать работу потоков в concurrent.futures?

Нет-нет.
.process_result вызовется, когда ваш worker уже отработает.
А если в реакции на кнопку “стоп” сделать
for f in self.pending:
f.cancel()
эффект будет другой.



Офлайн

#10 Янв. 27, 2011 09:27:15

Игнат
От:
Зарегистрирован: 2010-10-02
Сообщения: 224
Репутация: +  0  -
Профиль   Отправить e-mail  

как прервать работу потоков в concurrent.futures?

да, вроде я понял как это произойдет. и вызвать это надо в workere?

попробовал. теперь работает - проверка останавливается, спасибо большое.

но после такой остановки в консоли появляется:

  File "main.py", line 208, in worker
for f in self.pending:
RuntimeError: Set changed size during iteration
это вызвано тем что меняется размер self.pending?



Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version