Найти - Пользователи
Полная версия: I/O operation on closed file при многопоточности
Начало » Python для новичков » I/O operation on closed file при многопоточности
1 2 3
diam123
Доброго времени суток, господа, возникла такая проблема:
есть код
def main():
try:
page_src=urllib2.urlopen("http://"+site[:-1]).read()
except Exception:
print "ERROR"
else:
znach=parse("blablabla",page_src)# parse- это другая функция
print znach
lock.acquire()
with lock:
out.write(znach+"\n")
lock.release()
Есть многопоточность, реализована так:
        for site in site_list:
if threading.activeCount() < thr_num:
threading.Thread(target=main).start()
time.sleep(0.2)
if threading.activeCount() > thr_num:
threading.Thread(target=main).join()
На приблизительно 90 треде
вылазит:
Exception in thread Thread-90
Traceback (most recent call last):
File “C:\Python26\lib\threading.py”, line 522, in __bootstrap_inner
self.run()
File “C:\Python26\lib\threading.py”, line 477, in run
self.__target(*self.__args, **self.__kwargs)
File “C:\Python26\tic.py”, line 35, in main
out.write(znach+“\n”)
ValueError: I/O operation on closed file

Лок такого вида : lock=threading.RLock()

Как с этой проблемой справиться?
Queue не катит, для меня пока что рано

Заранее спасибо за ответы
slav0nic
out это что? StringIO?
diam123
slav0nic
out это что? StringIO?
with open (list_file+“outfile.txt”,“w”) as out:
Андрей Светлов
Без полного кода понять сложно. Очень похоже, что автор пытается “гладить кошку против шерсти”. Иногда (и недолго) можно избежать поцарапаных рук. В общем виде подход - фатален :)

Но кусок по мультипоточности сразу настораживает. Советую взять первый понравившийся thread pool и делать через него. Искать в google как “python threadpool”.
diam123
Честно говоря, и так привел почти полный код :) -в нем еще одна функция для парсинга да украшательства :) threadpool - не радует количество инфы на русском :) “В общем виде подход - фатален”- я пока что учусь, и благодарен за конструктивную критику, кстати, после того как
with open (list_file+“outfile.txt”,“w”) as out: заменил на out=open (list_file+“_statistics.txt”,“w”) и вместо замков поставил семафоры, вылетать перестало, зато начало тупо останавливаться приблизитeльно на 3/4 пути :), так что буду продолжать эксперименты и пытаться разобраться с ThreadPool.

Спасибо всем, кто уделил внимание и потратил свое время
slav0nic
для вывода в софтине с кучей тредов юзал logging, чего и тебе советую), ниразу проблем не было
shiza
diam123
Для кода в самом начале топика - у тебя там путаница =).
Поробуй так сделать:
1. Вместо RLock - использовать Lock.
2. для acquire() - сделать блокировку.
3. убрать with.
Т.е. так:
lock=threading.Lock()
.....
....
....
acquire(blocking=True)
out.write(znach+"\n")
lock.release()
diam123
*wall :mad:

Вот короче код:

#! /usr/bin/env python
# -*- coding:windows-1251 -*-
import urllib2,re,os,threading,time
counter=0

def main():
global counter
if counter>=20:
os.system('cls')
print "THREAD ACTIVE COUNT IS: "+str(threading.activeCount())
print " _____________________________________________________________________________ "
print "|SITE ADRESS |RESULT1 |RESULT2 |RESULT3 |RESULT4 |RESULT5 |"
print "|----------------------|----------|----------|----------|----------|----------|"
counter=0
site=site_list.pop()
try:
page_src=urllib2.urlopen("http://"+site[:-1]).read()
except Exception:
NEED_1=NEED_2=NEED_3=NEED_4=NEED_5="unreach."
else:
NEED_1=parse("NEED_1",page_src)
NEED_2=parse("NEED_2",page_src)
NEED_3=parse("NEED_3",page_src)
NEED_4=parse("NEED_4",page_src)
NEED_5=parse("NEED_5",page_src)
print "|"+site[:-1]+" "*(23-len(site))+"|"+NEED_1+" "*(10-len(NEED_1))+"|"+NEED_2+" "*(10-len(NEED_2))+"|"+NEED_3+" "*(10-len(NEED_3))+"|"+NEED_4+" "*(10-len(NEED_4))+"|"+NEED_5+" "*(10-len(NEED_5))+"|"
out.write("http://"+site[:-1]+"|"+NEED_1+"|"+NEED_2+"|"+NEED_3+"|"+NEED_4+"|"+NEED_5+"\n")
counter=counter+1

def parse(stroka,page_src):
find=page_src.find(stroka)
if find >=0:
numb=page_src[find:find+122]
if "<b>" in numb:
numb=numb[:40]
numb=re.findall(r'(<a href="/t/b\d+.torrent"> Bleach \d+ </a>)', numb) # В регулярках я полный 0 - использую готовое решение, где-то найденное
elif "</td>" in numb:
wid_f=numb.find('width="')
numb=numb[wid_f+10:]
numb=re.findall(r'(<a href="/t/b\d+.torrent"> Bleach \d+ </a>)', numb)
else:
numb=numb[:25]
numb=re.findall(r'(<a href="/t/b\d+.torrent"> Bleach \d+ </a>)', numb)
else:
numb=" not found "
numb=str(numb)[2:-2]
if "'," in numb:numb=numb[:numb.find("'")]
if numb=="":numb="non parsed"
return numb

print ""
list_file=raw_input("FILENAME :")
thr_num=int(raw_input("THREADS :"))
with open (list_file) as site_list:
with open (list_file[:-4]+"_statistics.txt","w") as out:
out.write("Адрес сайта"+"|"+"Результат1"+"|"+"Результат2"+"|"+"Результат3"+"|"+"Результат4"+"|"+"Результат5"+"|"+"\n")
print ""
print " _____________________________________________________________________________ "
print "|SITE ADRESS |RESULT1 |RESULT2 |RESULT3 |RESULT4 |RESULT5 |"
print "|----------------------|----------|----------|----------|----------|----------|"
site_list=list(site_list)
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()
Симптомы изложил выше

Замучился я уже :( Использовать ТредПул на 60 строчек (самый маленький и простой) для кода в 70 строк кажется ка-то некорректным, пожалуйста, подсоветуйте что нибудь в примерах, ато уже голова гудит…

P.S. Я знаю, что код ужасный - но это все, чего я смог добиться со своими знаниями….
P.P.S. Поубирал локи, так как и с ними и без них результат один и тот же
shiza
тыбы файл с урлами дал для примера…

а вообще попробуй так:
...
import urllib2,re,os,threading,time
lock = threading.Lock()
...
...
lock.acquire(blocking=True)
out.write("http://"+site[:-1]+"|"+NEED_1+"|"+NEED_2+"|"+NEED_3+"|"+NEED_4+"|"+NEED_5+"\n")
lock.release()
....
diam123
shiza
тыбы файл с урлами дал для примера…

а вообще попробуй так:
...
import urllib2,re,os,threading,time
lock = threading.Lock()
...
...
lock.acquire(blocking=True)
out.write("http://"+site[:-1]+"|"+NEED_1+"|"+NEED_2+"|"+NEED_3+"|"+NEED_4+"|"+NEED_5+"\n")
lock.release()
....
TypeError: acquire() takes no keyword arguments…
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