Форум сайта python.su
Добрый день !
Делаю почтовую многопоточную рассылку по стандартному примеру.
class Worker(threading.Thread): def __init__(self,queue): threading.Thread.__init__(self) self.__queue = queue def run(self): while True: try: item = self.__queue.get_nowait() # ждём данные except Queue.Empty: break # данные закончились, прекращаем работу try: self.work(item) # работа except Exception: traceback.print_exc() time.sleep(0.5) self.__queue.task_done() # задача завершена return def work(self,m): html_link = NewsletterHtml.objects.get(pk=m.html_data_id) msg = EmailMessage(m.subject, html_link.html, settings.DEFAULT_FROM_EMAIL, [m.email]) msg.content_subtype = "html" # Main content is now text/html try: print m.email msg.send() print m.email, '- Done' except (socket_error, SMTPRecipientsRefused, SMTPAuthenticationError), err: print 'Error' m.error = 1 m.sent = datetime.datetime.now() m.save() #-------------------------------------------------------------------------------------------------------------------------- if messages: for m in messages: queue.put(m) for i in xrange(num_threads): t = Worker(queue) # создаем поток t.start() # стартуем time.sleep(0.3) # чтобы в консоли друг на друга не накладывались
Офлайн
и сколько num_threads?
почитайте как глянуть backtrace имея core файл
Офлайн
slav0nic
Офлайн
#1396 0x281bcbf4 in ?? ()
#1397 0xbfbfe008 in ?? ()
#1398 0x00000000 in ?? ()
#1399 0x00000000 in ?? ()
#1400 0x00000000 in ?? ()
#1401 0x29739d40 in ?? ()
#1402 0x00000000 in ?? ()
#1403 0x00000000 in ?? ()
—Type <return> to continue, or q <return> to quit—
#1404 0x00000000 in ?? ()
Cannot access memory at address 0xbf9bd000
(gdb)
Только такой BT получается на freebsd
Офлайн
Во !
(gdb) bt
#0 0x28ccb1e5 in mcm_server_readable () from /usr/local/lib/libmemcache.so.4
#1 0x28ccd424 in mcm_get_line () from /usr/local/lib/libmemcache.so.4
#2 0x28ccf4be in mcm_fetch_cmd () from /usr/local/lib/libmemcache.so.4
#3 0x28cc3e65 in cmemcache_get_imp () from /usr/local/lib/python2.6/site-packages/_cmemcache.so
#4 0x0805c6c5 in PyObject_Call ()
#5 0x080b7d62 in PyEval_CallObjectWithKeywords ()
#6 0x0810295e in PyDescr_NewMethod ()
#7 0x2a23b8ac in ?? ()
#8 0x00000000 in ?? ()
#9 0x28ddaa6c in ?? ()
#10 0x00000000 in ?? ()
#11 0x08102a30 in PyDescr_NewMethod ()
#12 0x081028d0 in PyDescr_NewMethod ()
#13 0x28ddaa6c in ?? ()
#14 0xbf9bbbf8 in ?? ()
#15 0x0805c6c5 in PyObject_Call ()
Previous frame inner to this frame (corrupt stack?)
(gdb)
Офлайн
Что то тут ничего не поняно …
Офлайн
Может какая-то беда с *memcache.so, возможно стоит сначала обновить эти библиотеки, если они не последних стабильных версий
Офлайн
adw0rdСделал dummy кэш - упало на 200 сообщении (
Офлайн
Есть мнение, что в Вашем случае переполнение памяти связано именно с очередью сообщений. Так как процесс отправки почты небыстрый, то при пихании 8000 сообщений в очередь они там практически все и находятся, в оперативной памяти.
ПМСМ Вам надо отказаться от использования очереди и перейти к пулу потоков по типу multiprocessing.Pool. То есть программа должна:
1. Брать из пула свободный поток;
2. Вытаскивать из БД сообщение(я)
3. Передавать потоку сообщение(я) для отправки.
А если свободных потоков нет - тупо ждать пока не появятся.
Навскидку хороший пример организации пула дать не могу - поэтому дам, какой помню - http://www.openoffice.org/udk/python/oood/
Ну и отсылать по одному сообщению - очень долго из-за накладных расходов на установление соединения. Поскольку, большинство почтовых серверов позволяют отсылать сообщения пачками (штук по 20, как правило, проходит), то их и отправлять лучше пачками.
Отредактировано ziro (Авг. 25, 2012 11:29:20)
Офлайн
А почему нет t.join() ?
Офлайн