Уведомления

Группа в Telegram: @pythonsu

#1 Дек. 17, 2008 17:18:42

Viper
От:
Зарегистрирован: 2006-11-08
Сообщения: 137
Репутация: +  0  -
Профиль   Отправить e-mail  

I/O operation on closed file при многопоточности

Попробуй так, использованеи лока не обязательно, но должно предохранить от каши в результирующем файле

...
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)
......



Офлайн

#2 Дек. 17, 2008 20:21:40

diam123
От:
Зарегистрирован: 2008-10-23
Сообщения: 105
Репутация: +  0  -
Профиль   Отправить e-mail  

I/O operation on closed file при многопоточности

while threading.activeCount() > 1: заменил на if threading.activeCount() > 1: , так как если количество потоков >1 -то в результате ждал, пока их не станет 0, т.е работал только один поток :) Если time.sleep(1) то очень медленно работает, кол-во потоков около 2-4, ставил на 0.01 - та же проблема.. :(



Офлайн

#3 Дек. 18, 2008 11:48:17

Viper
От:
Зарегистрирован: 2006-11-08
Сообщения: 137
Репутация: +  0  -
Профиль   Отправить e-mail  

I/O operation on closed file при многопоточности

Этот while должен идти после for и нужен для того что б ждать пока завершатся все активные потоки, на быстродействие и на к-во запущенных потоков этот цикл влиять не должен.



Офлайн

#4 Дек. 18, 2008 19:32:10

shiza
От:
Зарегистрирован: 2007-07-03
Сообщения: 1073
Репутация: +  0  -
Профиль   Отправить e-mail  

I/O operation on closed file при многопоточности

diam123

diam123
TypeError: acquire() takes no keyword arguments…
Какая у тебя версия питона?

И дай наконец файл с урлами, чтоб я смог у себя попробовать.



Офлайн

#5 Дек. 18, 2008 21:31:33

diam123
От:
Зарегистрирован: 2008-10-23
Сообщения: 105
Репутация: +  0  -
Профиль   Отправить e-mail  

I/O operation on closed file при многопоточности

Python 2.6.1 а файл с урлами+программку я Вам личным сообщением отправил еще Вчера в 17:23:22… :)



Офлайн

#6 Дек. 18, 2008 22:16:59

diam123
От:
Зарегистрирован: 2008-10-23
Сообщения: 105
Репутация: +  0  -
Профиль   Отправить e-mail  

I/O operation on closed file при многопоточности

Viper
Перестало вылетать, зато теперь не хочет проходить по всему списку - примерно там же, где раньше была ошибка цикл заканчивается (ПОЧЕМУ ???)



Офлайн

#7 Дек. 18, 2008 22:29:05

shiza
От:
Зарегистрирован: 2007-07-03
Сообщения: 1073
Репутация: +  0  -
Профиль   Отправить e-mail  

I/O operation on closed file при многопоточности

Проблема в следующем:
главный поток останавливается не дождавшись завершения остальных нитей
и питон добросовестно закрывает 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)

Офлайн

#8 Дек. 18, 2008 23:35:26

diam123
От:
Зарегистрирован: 2008-10-23
Сообщения: 105
Репутация: +  0  -
Профиль   Отправить e-mail  

I/O operation on closed file при многопоточности

Спасибо огромное, все работает на ура !! Но только один минус- потоки бывает подвисают… И работает как кардиограмма… :) Нельзя ли как то прикрутить таймаут для потоков ?

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


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



Отредактировано (Дек. 18, 2008 23:37:18)

Офлайн

#9 Дек. 19, 2008 00:02:48

shiza
От:
Зарегистрирован: 2007-07-03
Сообщения: 1073
Репутация: +  0  -
Профиль   Отправить e-mail  

I/O operation on closed file при многопоточности

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

Для потоков - нельзя задать таймаут.
Можно задать таймаут для соединения, при скачке.
Например так (работает для питона 2.6):
urllib2.urlopen(blah-blah, timeout = 10)



Отредактировано (Дек. 19, 2008 00:03:36)

Офлайн

#10 Дек. 19, 2008 00:13:50

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

I/O operation on closed file при многопоточности

Поток подвисает, наверное, в 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 протокола не читал. Но не удивлюсь, если он это нормально держит - очень мощная библиотека.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version