Синхронизировать muti-threads в Python
Класс BrokenLinkTest в приведенном ниже коде делает следующее.
- принимает URL-адрес веб-страницы
- находит все ссылки на веб-странице.
- получать заголовки ссылок одновременно (это делается для проверки, не повреждена ли ссылка)
- print 'completed', когда все заголовки получены.
from bs4 import BeautifulSoup
import requests
class BrokenLinkTest(object):
def __init__(self, url):
self.url = url
self.thread_count = 0
self.lock = threading.Lock()
def execute(self):
soup = BeautifulSoup(requests.get(self.url).text)
self.lock.acquire()
for link in soup.find_all('a'):
url = link.get('href')
threading.Thread(target=self._check_url(url))
self.lock.acquire()
def _on_complete(self):
self.thread_count -= 1
if self.thread_count == 0: #check if all the threads are completed
self.lock.release()
print "completed"
def _check_url(self, url):
self.thread_count += 1
print url
result = requests.head(url)
print result
self._on_complete()
BrokenLinkTest("http://www.example.com").execute()
Можно ли выполнить concurrency/синхронизацию. Я сделал это с помощью threading.Lock. Это мой первый эксперимент с потоками python.
Ответы
Ответ 1
def execute(self):
soup = BeautifulSoup(requests.get(self.url).text)
threads = []
for link in soup.find_all('a'):
url = link.get('href')
t = threading.Thread(target=self._check_url, args=(url,))
t.start()
threads.append(t)
for thread in threads:
thread.join()
Вы можете использовать метод join
для ожидания завершения всех потоков.
Примечание. Я также добавил начальный вызов и передал объект связанного метода в целевой параметр. В вашем исходном примере вы вызывали _check_url
в основном потоке и передавали возвращаемое значение целевому параметру.
Ответ 2
Все потоки в Python работают на одном ядре, поэтому вы не будете получать какую-либо производительность, делая это таким образом. Также - очень неясно, что на самом деле происходит?
- Вы никогда не запускаете нити, вы просто инициализируете его.
- Нити сами по себе не имеют ничего общего, кроме уменьшения количества потоков
Вы можете получить производительность только в потоковом сценарии, если ваша программа выполняет работу с IO (отправка запросов, запись в файл и т.д.), где в то же время могут работать другие потоки.