Найти - Пользователи
Полная версия: как прервать работу потоков в concurrent.futures?
Начало » Python для новичков » как прервать работу потоков в concurrent.futures?
1 2
Игнат
здравствуйте

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

запускаю так:
        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

ничего не помогает, всё работает как работало
подскажите, что нужно сделать, чтобы корректно убить все созданные потоки и не плодить новых?
Андрей Светлов
Вот именно флаг и должен помогать. Нужно остановится - проверили это в self.worker и завершились.
Фраза вроде: “я все перепробовал, но ничего не подошло” не очень информативна.
Игнат
пробовал так:
    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('останавливаем проверку')
Андрей Светлов
Стоп-стоп.
У вас 100 заданий. 35 закончились, 10 еще работают, 45 ждут свободных потоков в executor.
Что должна сделать остановка?
Игнат
прервать оставшихся. чтобы они, получив свободные потоки - не чекали прокси, не делали свою работу, а просто завершались тихо
Игнат
кто-нибудь знает как это сделать?
Андрей Светлов
Послушайте. У вас же есть self.pending.
Сделайте для них .cancel
Или я чего-то не понимаю?
Игнат
так я же делал:

    def process_result(self, future):

self.pending.discard(future)

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

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

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

но после такой остановки в консоли появляется:
  File "main.py", line 208, in worker
for f in self.pending:
RuntimeError: Set changed size during iteration
это вызвано тем что меняется размер self.pending?
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