Namecheap.com - Cheap domain name registration, renewal and transfers - Free SSL Certificates - Web Hosting

Распараллеливание задач. Python. Web. #1

Wednesday, August 19th, 2009

Даже забыл что в блогах модно к каждому посту клеить бессмысленное тематическое изображение, вообщем начинаю так же следовать традициям.

Тема поста, как можно догадаться из названия потоки. Если однопоточное приложение – это конвеер, то многопоточное – целый завод, позволяющий выпускать больше “фирменной продукции” за меньшее время (более эффективно использовать вычислительные ресурсы). Другими словами потоки безусловно полезная тема, которая стоит того, чтобы потратить некоторое время на изучение, чтобы так сказать познать ДАО. Тема объемная, сам я тоже не профессиональный программист, нет никакой возможности описать все одним постом => разобью задачу на подзадачи.

Python – Global Interpreter Lock (GIL)

Python обладает некоторым преимуществом в реализации потоков по сравнению с php (по крайней мере так принято считать), но как обычно не все так гладко =) Python – интерпретатор, и если верить девелоперам существует проблема которая называется GIL – global interpreter lock.

При своей работе основной интерпретатор Python постоянно использует большое количество потоково-небезопасных данных. В основном это словари, в которых хранятся атрибуты объектов. Для избежания разрушения этих данных при совместной модификации из разных потоков перед началом исполнения нескольких инструкций (по умолчанию 100) поток интерпретатора захватывает GIL, а по окончании освобождает. Вследствие этой особенности в каждый момент времени может исполняться только один поток Python кода, даже если в компьютере имеется несколько процессоров или процессорных ядер.

Взял из википедии

Смысл всего написанного – программы на питоне медленные, однако сфера нашей деятельности – Web, где мы все время чего-то ждем (таймауты, чтобы не задрочить гугл, ожидание ответа сервера и т.д.), и соответственно скорость выполнения на уровне кода существенно не роляет.

Если интересуют детали – более подробно и наглядно про GIL можно почитать в этом дукументе или посмотреть видео.

Ближе к делу – пора сделать что-нибудь полезное.

Пингуем сайты

Предположим, что вы счастливый вледелец целой сетки блогов/сайтов разбросанных для надежности и перелинковки по разным хостингам. Хорошо было бы переодически проверять сайты на работоспособность, ок – можно проверить вбивая адреса в браузер. Это замечательно если сайтов меньше 10, а если 100? или 1000? Проверка большого количества может стать действительно проблемой которая сожрет кучу времени (хехе я бы на самом деле положил болт на это занятие и уверен 90% вебмастеров поступили бы точно так же). Но тут грамотного вебмастера может выручить несложная автоматизация.

Собственно можно пойти 2я путями – тупо вызывать утилиту ping и парсить результаты, или использовать сокеты для того чтобы формировать/отправлять/получать пакеты используя стандартный потокол ICMP. 1ый способ годится если гонять программку на строго заданной ос, 2ой более универсален.

Собственно реализация 1го способа для Linux который я выдрал где-то в интернете :

import os
import re
import time
import sys
from threading import Thread

class testit(Thread):
    def __init__ (self,ip):
        Thread.__init__(self)
        self.ip = ip
        self.status = -1
    def run(self):
        pingaling = os.popen("ping -q -c2 "+self.ip,"r")
        while 1:
            line = pingaling.readline()
            if not line: break
            igot = re.findall(testit.lifeline,line)
            if igot:
                self.status = int(igot[0])

testit.lifeline = re.compile(r"(\d) received")
report = ("No response","Partial Response","Alive")

print time.ctime()

pinglist = []

for host in range(60,70):
    ip = "192.168.200."+str(host)
    current = testit(ip)
    pinglist.append(current)
    current.start()

for pingle in pinglist:
    pingle.join()
    print "Status from ",pingle.ip,"is",report[pingle.status]

print time.ctime()

2ой способ который я слепил из сниппетов можно скачать тут.

Нетрудно заметить – кода больше, но много лишнего, пример написан на скорую руку но тем не менее все должно быть понятно. Есть только одно “но”, если список хостов довольно объемный программа породит огромное количество потоков (по одному на каждый), что не совсем верно, это распиздяйский подход. Чтобы этого избежать реализуется так называемый пул потоков (thread pool) – т.е. создание ограниченного числа потоков которые обрабатывают задания из очереди. Это тема следующей статьи.

My blog is Do-Follow


Пишу код, делаю сайты.
Check out my about.me profile!

парсинг сайтов, форумов, интернет магазинов

Want to subscribe?

istinspring twitter account
istinspring facebook account

 Subscribe in a reader Or, subscribe via email:
Enter your email address:  
Find entries :