Форум сайта python.su
Попробуй так, использованеи лока не обязательно, но должно предохранить от каши в результирующем файле
...
import urllib2,re,os,threading,time
lock = threading.Lock()
...
...
lock.acquire()
out.write("http://"+site[:-1]+"|"+NEED_1+"|"+NEED_2+"|"+NEED_3+"|"+NEED_4+"|"+NEED_5+"\n")
lock.release()
....
for site in site_list:
if threading.activeCount() < thr_num:
threading.Thread(target=main).start()
time.sleep(0.5)
if threading.activeCount() > thr_num:
threading.Thread(target=main).join()
while threading.activeCount() > 1:
time.sleep(1)
......
Офлайн
while threading.activeCount() > 1: заменил на if threading.activeCount() > 1: , так как если количество потоков >1 -то в результате ждал, пока их не станет 0, т.е работал только один поток :) Если time.sleep(1) то очень медленно работает, кол-во потоков около 2-4, ставил на 0.01 - та же проблема.. :(
Офлайн
Этот while должен идти после for и нужен для того что б ждать пока завершатся все активные потоки, на быстродействие и на к-во запущенных потоков этот цикл влиять не должен.
Офлайн
diam123
diam123Какая у тебя версия питона?
TypeError: acquire() takes no keyword arguments…
Офлайн
Python 2.6.1 а файл с урлами+программку я Вам личным сообщением отправил еще Вчера в 17:23:22… :)
Офлайн
ViperПерестало вылетать, зато теперь не хочет проходить по всему списку - примерно там же, где раньше была ошибка цикл заканчивается (ПОЧЕМУ ???)
Офлайн
Проблема в следующем:
главный поток останавливается не дождавшись завершения остальных нитей
и питон добросовестно закрывает out файл (открыт-то он в главном потоке), из-за чего и получается ошибка.
По идее главный поток должен дождаться окончания всех запущенных нитей.
У вас путаница с тем, как это делать правильно.
Обычный паттерн использования такой:
work_threads = [] #список нитей
for i in xrange(10):
th = threading.Thread(...) #создаем нить
th.start() #запускаем
work_threads.append(th) #добавляем в список
for th in work_threads: #для всех нитей
th.join() #ждем завершения
Отредактировано (Дек. 18, 2008 22:29:38)
Офлайн
Спасибо огромное, все работает на ура !! Но только один минус- потоки бывает подвисают… И работает как кардиограмма… :) Нельзя ли как то прикрутить таймаут для потоков ?
Спасибо огромное Viper за помощь
И еще большее СПАСИБО SHIZA за решение проблемы
Отредактировано (Дек. 18, 2008 23:37:18)
Офлайн
diam123:)
И еще большее СПАСИБО SHIZA за решение проблемы
Отредактировано (Дек. 19, 2008 00:03:36)
Офлайн
Поток подвисает, наверное, в urllib2.urlopen("http://"+site).read()
Можно сократить время ожидания.
В Python 2.5 - socket.setdefaulttimeout
В Python 2.6 добавился timeout параметр в urllib2, насколько я помню.
“Рваная картинка” может быть по двум причинам.
- Долго подключается новое соединение
- Долго создается новый поток (эта операция действительно довольно накладная).
Первая проблема легко не решается. Нужно спуститься на уровень ниже и работать с http через keep-alive соединение (если сервер его поддерживает, конечно. Обычно - поддерживает).
Вторая решается через threadpool - он уже держит нужное количество потоков и не создает новые, только загружает уже существующие.
Возможно, простым способом будет использование pycurl в режиме multi - slav0nic буквально на днях хвалил. Я curl на keep-alive не тестил и исходников по реализации http протокола не читал. Но не удивлюсь, если он это нормально держит - очень мощная библиотека.
Офлайн