Уведомления

Группа в Telegram: @pythonsu

#1 Март 12, 2012 17:46:30

Soteric
От:
Зарегистрирован: 2010-09-19
Сообщения: 352
Репутация: +  20  -
Профиль   Отправить e-mail  

Многопоточность

Я имел ввиду одновременно. Наверное можно так

for thread in threads:
thread.join()
но никогда не видел такой код. Может быть просто не понял идеи. По-моему, потоки отрапортовали, что очередь обработана, мы можем двигаться дальше. Что там потом произойдет с потоками - вернутся они в какой-то пул или завершатся или уснут и будут ждать когда в очереди появится что-то еще - это все нам неинтересно. В противном случае нам придется учитывать реализацию этих потоков. Конкретно для этой задачи я думаю не принципиально, результат одинаковый :)



Отредактировано (Март 12, 2012 17:53:41)

Офлайн

#2 Март 13, 2012 16:57:55

Mozart
От:
Зарегистрирован: 2011-12-12
Сообщения: 66
Репутация: +  0  -
Профиль   Отправить e-mail  

Многопоточность

В общем разобрался я, убрал из кода суп полностью, оставил только регулярки, теперь чувствуется что работают потоки…

# -*- 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 и помог ))



Отредактировано (Март 13, 2012 17:01:13)

Офлайн

#3 Март 14, 2012 13:59:18

Lexander
От:
Зарегистрирован: 2008-09-19
Сообщения: 1139
Репутация: +  33  -
Профиль   Отправить e-mail  

Многопоточность

Mozart
Без thread_.join() ваша программа работает неправильно ;)
Еще раз: напишите в последнем raw_input(“”) непустое сообщение и запустите скрипт - поймете зачем нужен join.



Офлайн

#4 Март 14, 2012 21:21:19

shs666
От:
Зарегистрирован: 2012-03-06
Сообщения: 12
Репутация: +  0  -
Профиль   Отправить e-mail  

Многопоточность

Чтобы не плодить темы, решил отпостить свой небольшой вопрос тут.

Имеется класс Qhtread.
В теле Run() запускается функция, которая создает несколько простых потоков (Thread).
Дело в том, что Qthread не дожидается их завершения. Просто запускает потоки и Run завершается (return), а простые потоки продолжают работу, пока не выполнят задачу…

Можно каким-нибудь методом ожидать завершения этих потоков?



Офлайн

#5 Март 14, 2012 21:40:12

Soteric
От:
Зарегистрирован: 2010-09-19
Сообщения: 352
Репутация: +  20  -
Профиль   Отправить e-mail  

Многопоточность

Как сказал Lexander, нужно вызывать метод join() у потоков. В этом случае выполнение Qthread будет приостановлено до получения сигнала или смерти Thread.



Офлайн

#6 Март 15, 2012 07:07:12

shs666
От:
Зарегистрирован: 2012-03-06
Сообщения: 12
Репутация: +  0  -
Профиль   Отправить e-mail  

Многопоточность

Программа многопоточная. Каждый поток выполняет свою задачу. Если использовать join(), то новый поток не создастся и не будет параллельно работать, пока не завершится предыдущий.



Отредактировано (Март 15, 2012 07:07:54)

Офлайн

#7 Март 15, 2012 14:23:32

cutwater
От:
Зарегистрирован: 2009-01-08
Сообщения: 444
Репутация: +  19  -
Профиль   Отправить e-mail  

Многопоточность

shs666
Программа многопоточная. Каждый поток выполняет свою задачу. Если использовать join(), то новый поток не создастся и не будет параллельно работать, пока не завершится предыдущий.
ЛОЛШТО. Еще раз. Создать несколько потоков, запустить их. Потом вызвать join.

for thread in threads:
thread.join()



Офлайн

#8 Март 15, 2012 15:55:04

shs666
От:
Зарегистрирован: 2012-03-06
Сообщения: 12
Репутация: +  0  -
Профиль   Отправить e-mail  

Многопоточность

Спасибо помогло :)
На самом деле я неправильно использовал join.



Офлайн

#9 Март 15, 2012 20:05:14

Mozart
От:
Зарегистрирован: 2011-12-12
Сообщения: 66
Репутация: +  0  -
Профиль   Отправить e-mail  

Многопоточность

Lexander, в общем я понял что при использовании join() следующий поток будет ждать завершения работы начатого первого потока неограниченное количество времени, если не указан таймаут. Да и по повду raw_input() - написал там пару символов, без join() они выпадают сразу, т.е. программа считается завершенной, но очередь висит и потоки продолжают работать, а вот с join() программа будет ждать завершения работы всех потоков …



Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version