Найти - Пользователи
Полная версия: Грамотная работа с потоками
Начало » Python для новичков » Грамотная работа с потоками
1
InPython
Друзья подскажите как правильно работать с потоками, на примере простенького парсера.
вот код который собирает ники со страничек этого форума
import urllib, re, time
start, f, count = time.time(), open("user.txt", "w+"), 115
while True:
if count == 122:
f.close()
print 'collection time:', time.time() - start, '\n', 'collected:', str(len(open('user.txt', 'r').readlines()))
break
for user in (re.findall('profile.php\?id=\d+\">([^<]+)</a>', urllib.urlopen('http://python.su/forum/userlist.php?username=&show_group=-1&sort_by=username&sort_dir=ASC&p='+str(count)).read())):
f.write(user + '\n')
print user
count += 1
а вот вариант с использованием потоков
import urllib, re, threading, Queue
f, queue = open("user.txt", "w+"), Queue.Queue()
def start():
while True:
if queue.empty():
if t.isAlive():
break
break
for user in (re.findall('profile.php\?id=\d+\">([^<]+)</a>', urllib.urlopen(queue.get()).read())):
f.write(user + '\n')
print user
queue.task_done()
for count in [x for x in xrange(115, 122, 1)]:
queue.put('http://python.su/forum/userlist.php?username=&show_group=-1&sort_by=username&sort_dir=ASC&p='+str(count))
for i in xrange(5):
t = threading.Thread(target = start)
t.start()
queue.join()
Скажите пожалуйста как правильно завершить работу всех потоков и закрыть файл? Как можно оптимизировать\улучшить данный код в целом?
p.s. форум в качестве рабочего примера выбран исключительно для самообразования.
Андрей Светлов
import urllib, re, threading, Queue
f, queue = open("user.txt", "w+"), Queue.Queue()

def start():
while True:
item = queue.get()
if item is None:
queue.task_done()
return
data = urllib.urlopen(item).read()
for user in (re.findall('profile.php\?id=\d+\">([^<]+)</a>', data)):
f.write(user + '\n')
print user
queue.task_done()


for count in [x for x in xrange(115, 122, 1)]:
queue.put('http://python.su/forum/userlist.php?username=&show_group=-1&sort_by=username&sort_dir=ASC&p='+str(count))

threads = []
for i in xrange(5):
t = threading.Thread(target = start)
threads.append(t)
t.start()

for t in threads:
queue.put(None)

queue.join()
for t in threads:
t.join()
А настоящие герои всегда идут в обход:
http://docs.python.org/py3k/library/concurrent.futures.html#threadpoolexecutor-example
Ed
Я бы посоветовал еще глянуть в сторону Asyncore: http://www.doughellmann.com/PyMOTW/asyncore/
По-моему как раз для таких случаев сделан.
InPython
Андрей Светлов
Спасибо большое так, понятней стало. и еще… Вы привели ссылку код питона третьей версии, с какой версией лучше работать?
Ed
думаю работать с классами мне пока рановато ;)
Андрей Светлов
Работаете уже с двойкой — продолжайте это делать. Пока не почувствуете себя более или менее уверенно.
Для concurent.futures есть версия, работающая и на двойке: http://pypi.python.org/pypi/futures
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