Найти - Пользователи
Полная версия: I/O operation on closed file при многопоточности
Начало » Python для новичков » I/O operation on closed file при многопоточности
1 2 3
Viper
Попробуй так, использованеи лока не обязательно, но должно предохранить от каши в результирующем файле
...
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)
......
diam123
while threading.activeCount() > 1: заменил на if threading.activeCount() > 1: , так как если количество потоков >1 -то в результате ждал, пока их не станет 0, т.е работал только один поток :) Если time.sleep(1) то очень медленно работает, кол-во потоков около 2-4, ставил на 0.01 - та же проблема.. :(
Viper
Этот while должен идти после for и нужен для того что б ждать пока завершатся все активные потоки, на быстродействие и на к-во запущенных потоков этот цикл влиять не должен.
shiza
diam123
diam123
TypeError: acquire() takes no keyword arguments…
Какая у тебя версия питона?

И дай наконец файл с урлами, чтоб я смог у себя попробовать.
diam123
Python 2.6.1 а файл с урлами+программку я Вам личным сообщением отправил еще Вчера в 17:23:22… :)
diam123
Viper
Перестало вылетать, зато теперь не хочет проходить по всему списку - примерно там же, где раньше была ошибка цикл заканчивается (ПОЧЕМУ ???)
shiza
Проблема в следующем:
главный поток останавливается не дождавшись завершения остальных нитей
и питон добросовестно закрывает out файл (открыт-то он в главном потоке), из-за чего и получается ошибка.

По идее главный поток должен дождаться окончания всех запущенных нитей.
У вас путаница с тем, как это делать правильно.
Обычный паттерн использования такой:
work_threads = [] #список нитей
for i in xrange(10):
th = threading.Thread(...) #создаем нить
th.start() #запускаем
work_threads.append(th) #добавляем в список

for th in work_threads: #для всех нитей
th.join() #ждем завершения
diam123
Спасибо огромное, все работает на ура !! Но только один минус- потоки бывает подвисают… И работает как кардиограмма… :) Нельзя ли как то прикрутить таймаут для потоков ?

Спасибо огромное Viper за помощь


И еще большее СПАСИБО SHIZA за решение проблемы
shiza
diam123
И еще большее СПАСИБО SHIZA за решение проблемы
:)

Для потоков - нельзя задать таймаут.
Можно задать таймаут для соединения, при скачке.
Например так (работает для питона 2.6):
urllib2.urlopen(blah-blah, timeout = 10)
Андрей Светлов
Поток подвисает, наверное, в 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 протокола не читал. Но не удивлюсь, если он это нормально держит - очень мощная библиотека.
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