Форум сайта python.su
питон 3.1
есть класс. он содержит куеуе:
self.queue = queue.Queue()
def threadMain(self):
import queue
while True:
try:
target = self.queue.get_nowait()
except queue.Empty:
return 0
Отредактировано (Ноя. 13, 2010 20:34:02)
Офлайн
Прекратите издеваться.
Очередь пустая - будет исключение.
У вас, наверное, такое не происходит - вот и прокатывает.
Уберите import queue из функции. Импорт внутри потока возможен, но иногда бьет по рукам - есть пара ньюансов.
Офлайн
не было и в мыслях над кем-нибудь издеваться
если бы я понимал как это работает и знал отличия 2.6 от 3.1, вполне вероятно что мне хватило бы и гугла
>>Так ищите raise Empty
вот основная проблема!
0. except Empty:
NameError: global name ‘Empty’ is not defined
1.
self.queue = queue.Queue()
except self.queue.Empty:
AttributeError: ‘Queue’ object has no attribute ‘Empty’
2 except queue.Empty:
NameError: global name ‘queue’ is not defined
3 except Queue.Empty:
NameError: global name ‘Queue’ is not defined
объясните пожалуйста, к чему обращаться? к глобальному имени queue, к его экземпляру self.queue = queue.Queue(), и почему у них обоих нет атрибута Empty?
и если глобальный нельзя подключить импортом, то почему экземпляр не имеет такого атрибута?
Офлайн
Издевались те, кто пытался вам отвечать.
Исключение не в классе Queue а в модуле queue.
Делать как-то так:
import queue
import time
class A(object):
def __init__(self):
self.queue = queue.Queue()
def put(self, val):
self.queue.put(val)
def process(self):
while True:
try:
val = self.queue.get_nowait()
# process val
except queue.Empty:
time.sleep(1) # just for example
def get(self, block=True, timeout=None):
"""Remove and return an item from the queue.
If optional args 'block' is true and 'timeout' is None (the default),
block if necessary until an item is available. If 'timeout' is
a positive number, it blocks at most 'timeout' seconds and raises
the Empty exception if no item was available within that time.
Otherwise ('block' is false), return an item if one is immediately
available, else raise the Empty exception ('timeout' is ignored
in that case).
"""
self.not_empty.acquire()
try:
if not block:
if not self._qsize():
raise Empty
elif timeout is None:
while not self._qsize():
self.not_empty.wait()
elif timeout < 0:
raise ValueError("'timeout' must be a positive number")
else:
endtime = _time() + timeout
while not self._qsize():
remaining = endtime - _time()
if remaining <= 0.0:
raise Empty
self.not_empty.wait(remaining)
item = self._get()
self.not_full.notify()
return item
finally:
self.not_empty.release()
def get_nowait(self):
"""Remove and return an item from the queue without blocking.
Only get an item if one is immediately available. Otherwise
raise the Empty exception.
"""
return self.get(False)
Офлайн
спасибо за подробный ответ
ошибка была в том, что import queue стоял в начале конструктора, а не в начале файла.
но всё же -
while True:
try:
acc = self.queue.get_nowait()
except queue.Empty:
print('empty!')
return 0
acc = self.queue.get_nowait()
Офлайн
Уверены, что потоки таки работают?
Я бы скорее предположил (всего кода не вижу, поэтому догадываюсь), что ваши потоки попросту тихо умирают по этому самому queue.Empty, никому об этом не говоря.
Офлайн
не, программа-то работает
причем правильно
каждый поток делает свое дело
сейчас лишний раз убедился
Офлайн
сеанс гадания закончен. Больше ничего по вашим шести строчкам сказать не могу.
Офлайн
вот полный код
все незначительные методы гуи опущены, функция check() - это основная задача потока, она работает нормально. изначально она была сделана для однопоточной версии, там тем более все в порядке
проверку исключения закомментировал, сразу за ней идет получение задачи из queue без проверок
import sys
import sip
from PyQt4 import QtCore, QtGui
from ui import Ui_Form
import queue
from lib import check
class run(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_Form()
self.ui.setupUi(self)
self.queue = queue.Queue()
# connectors
###
QtCore.QObject.connect(self.ui.button_start,
QtCore.SIGNAL("clicked()"),
self.start)
def unique(self): #
def load(self): #
def clear(self): #
def setLabelTotal(self, num): #
def labelValidInc(self): #
def labelInvalidInc(self): #
def labelTotalDec(self): #
def start(self):
import threading
''' check accounts mt '''
accs = self.ui.text_accs.toPlainText().splitlines()
for acc in accs:
self.queue.put(acc)
for test in range(len(accs)):
new_thread = threading.Thread(target=self.threadMain)
new_thread.start()
threading.Thread.join(new_thread)
def threadMain(self):
''' thread body '''
global app
## while True:
## try:
## acc = self.queue.get_nowait()
## except queue.Empty:
## print('empty!')
## return 0
acc = self.queue.get_nowait() # work
res = check(acc) # thread body (not included)
newAccsText = self.ui.text_accs.toPlainText().replace(acc, '')
if res == 1:
self.ui.text_accs_valid.appendPlainText(acc)
self.labelValidInc()
else:
self.labelInvalidInc()
self.ui.text_accs.setPlainText(newAccsText.strip())
self.labelTotalDec()
app.processEvents() # update gui
##################################################################
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myApp = run()
myApp.show()
sys.exit(app.exec_())
Офлайн
Ошибка была в threadMain - уберите while и будет вам счастье. Но недолго.
Без ножа режете - так с потоками обращаться. Не нужно делать их столько.
Есть такое понятие - thread pool. Как раз для подобных задачек придумано.
import sys
import sip
from PyQt4 import QtCore, QtGui
from ui import Ui_Form
#import queue
#import threading
# install from http://pypi.python.org/pypi/futures
# doc in http://www.python.org/dev/peps/pep-3148/
from concurency.futures import ThreadPoolExecutor
from lib import check
class run(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_Form()
self.ui.setupUi(self)
self.executor = ThreadPoolExecutor(max_workers=5) # should be relative small
self.pending = set()
self.queue = queue.Queue()
# connectors
###
QtCore.QObject.connect(self.ui.button_start,
QtCore.SIGNAL("clicked()"),
self.start)
def closeEvent(self, event):
event.accept()
for p in self.pendings:
p.cancel()
self.executor.shutdown() # wait for processing all pending tasks
def unique(self): pass#
def load(self): pass#
def clear(self): pass#
def setLabelTotal(self, num): pass#
def labelValidInc(self): pass#
def labelInvalidInc(self): pass#
def labelTotalDec(self): pass#
def start(self):
''' check accounts mt '''
accs = self.ui.text_accs.toPlainText().splitlines()
for acc in accs:
future = self.executor.submit(self.worker, acc)
self.pending.add(future)
future.add_done_callback(self.process_result)
def process_result(self, future):
# callback is called in main thread
# it's good practice to communicate with UI in main thread only
self.pending.discard(future)
if future.cancelled():
# cancelled on shutdown
return
acc, res = future.result()
newAccsText = self.ui.text_accs.toPlainText().replace(acc, '')
if res == 1:
self.ui.text_accs_valid.appendPlainText(acc)
self.labelValidInc()
else:
self.labelInvalidInc()
self.ui.text_accs.setPlainText(newAccsText.strip())
self.labelTotalDec()
def worker(self, acc):
# worker precesses own code in one of executor threads
res = check(acc) # thread body (not included)
return acc, res
##################################################################
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myApp = run()
myApp.show()
sys.exit(app.exec_())
Офлайн