Soteric
Март 12, 2012 17:46:30
Я имел ввиду одновременно. Наверное можно так
for thread in threads:
thread.join()
но никогда не видел такой код. Может быть просто не понял идеи. По-моему, потоки отрапортовали, что очередь обработана, мы можем двигаться дальше. Что там потом произойдет с потоками - вернутся они в какой-то пул или завершатся или уснут и будут ждать когда в очереди появится что-то еще - это все нам неинтересно. В противном случае нам придется учитывать реализацию этих потоков. Конкретно для этой задачи я думаю не принципиально, результат одинаковый :)
Mozart
Март 13, 2012 16:57:55
В общем разобрался я, убрал из кода суп полностью, оставил только регулярки, теперь чувствуется что работают потоки…
# -*- coding: cp1251 -*-
import urllib, urlparse, re, Queue, threading, time
queue = Queue.Queue()
lock = threading.RLock()
threads_count = 15
url_start = "http://site.ru"
url_end = "sitemap.xml"
url = urlparse.urljoin(url_start, url_end)
print u"Ждите ..."
link = urllib.urlopen(url)
links = str(link.read())
k = 1
list = []
p1 = re.compile(r"<loc>(.*?)</loc>", re.S | re.I)
p2 = re.compile(r"<meta\sname=\"Keywords\"\scontent=\"(.*)\">\n<meta\sname", re.S | re.I)
def worker():
global queue
while 1:
try:
target = queue.get_nowait()
starting(target)
except Queue.Empty:
return
def starting(gg):
global k, p2
try:
link1 = urllib.urlopen(gg)
b = p2.findall(link1.read())
c = "".join(b).decode("cp1251")
link1.close()
print u"Спарсили ключевик № " + str(k)
finally:
lock.acquire()
f = open("file1.txt", "a")
f.write(c.encode("cp1251") + "\n")
lock.release()
k += 1
def main():
global p1
for i in p1.findall(links):
queue.put(i)
for _ in xrange(threads_count):
thread_ = threading.Thread(target=worker)
thread_.start()
link.close()
q = raw_input("Parse ? y/n: ")
if q == "y":
main()
else:
print "Okay ..."
raw_input("")
Правда с кодировками я пол дня мучался, только join и помог ))
Lexander
Март 14, 2012 13:59:18
Mozart
Без thread_.join() ваша программа работает неправильно ;)
Еще раз: напишите в последнем raw_input(“”) непустое сообщение и запустите скрипт - поймете зачем нужен join.
shs666
Март 14, 2012 21:21:19
Чтобы не плодить темы, решил отпостить свой небольшой вопрос тут.
Имеется класс Qhtread.
В теле Run() запускается функция, которая создает несколько простых потоков (Thread).
Дело в том, что Qthread не дожидается их завершения. Просто запускает потоки и Run завершается (return), а простые потоки продолжают работу, пока не выполнят задачу…
Можно каким-нибудь методом ожидать завершения этих потоков?
Soteric
Март 14, 2012 21:40:12
Как сказал Lexander, нужно вызывать метод join() у потоков. В этом случае выполнение Qthread будет приостановлено до получения сигнала или смерти Thread.
shs666
Март 15, 2012 07:07:12
Программа многопоточная. Каждый поток выполняет свою задачу. Если использовать join(), то новый поток не создастся и не будет параллельно работать, пока не завершится предыдущий.
cutwater
Март 15, 2012 14:23:32
shs666
Программа многопоточная. Каждый поток выполняет свою задачу. Если использовать join(), то новый поток не создастся и не будет параллельно работать, пока не завершится предыдущий.
ЛОЛШТО. Еще раз. Создать несколько потоков, запустить их. Потом вызвать join.
for thread in threads:
thread.join()
shs666
Март 15, 2012 15:55:04
Спасибо помогло :)
На самом деле я неправильно использовал join.
Mozart
Март 15, 2012 20:05:14
Lexander, в общем я понял что при использовании join() следующий поток будет ждать завершения работы начатого первого потока неограниченное количество времени, если не указан таймаут. Да и по повду raw_input() - написал там пару символов, без join() они выпадают сразу, т.е. программа считается завершенной, но очередь висит и потоки продолжают работать, а вот с join() программа будет ждать завершения работы всех потоков …