Pular para o conteúdo

Threads simples com Python

12 abril 2012

Hoje pesquisando fiz um código para usar threads com python, ob objetivo era uma classe que eu pudesse jogar vários downloads e eles rodassem cada um numa thread. Outra coisa legal é que me desafiei a usar somente python3 de agora em diante.

Então comecei assim:

import threading
import urllib

class fGet(threading.Thread):
	def __init__(self, url, arq):
		self.url = url
		self.arq = arq
		self.result = None
		threading.Thread.__init__(self)

	def run(self):
		f = urllib.URLopener()
		self.result = f.retrieve(self.url,self.arq)

Comecei importando os módulos threading e urllib, o threading vai fazer a parte das threads e o urllib vai ser a lib que vai fazer meu download.

Dessa forma eu já poderia fazer:

15:20:19|nilson|0|2111|~/tmp> python
Python 2.7.2+ (default, Oct 4 2011, 20:06:09)
[GCC 4.6.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from filegetter import fGet
>>> f = fGet("http://www.python.org/images/python-logo.gif","python.gif")
>>> f.start()
>>>
15:22:15|nilson|0|2112|~/tmp> ls *.gif
-rw-rw-r-- 1 nilson nilson 2,5K 2012-04-12 15:22 python.gif

Veja que ficou uma beleza, ele baixou a imagem sem problemas, porém, algumas outras coisas devem ser pensadas, são elas:

– E se der erro?
– Como retorno esses erros?
– Como sei que a thread inicou/terminou?

Após algumas modificações eu cheguei nesse código:

#!/usr/bin/env python

import threading
import datetime
import urllib
import time

class fGet(threading.Thread):
  def __init__(self, url, arq):
    self.url = url
    self.arq = arq
    self.result = None
    self.trys = 2
    threading.Thread.__init__(self)

  def run(self):
    try:
      print("%s started (#%s try) [%s]" % (self.getName(), 3-self.trys,datetime.datetime.now()))
      f = urllib.URLopener()
      self.result = f.retrieve(self.url,self.arq)
      print("%s finished [%s]" % (self.getName(), datetime.datetime.now()))
    except Exception as e:
      self.result = e
      print("%s Exception: %s [%s]" % (self.getName(), e, datetime.datetime.now()))
      if self.trys > 0:
        self.trys=self.trys-1
        time.sleep(2)
        self.run()

Adicionei umas mensagens de status, e criei um mecanismo onde a thread tenta até 3 vezes baixar o arquivo, no caso de dar erro na primeira vez.

O funcionamento dela ficou assim:

16:31:15|nilson|0|2138|~/tmp> python
Python 2.7.2+ (default, Oct 4 2011, 20:06:09)
[GCC 4.6.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from fileg import fGet
>>> f = fGet("http://www.python.org/images/python-logo.gif","python.gif")
>>> f.start()
Thread-1 started (#1 try) [2012-04-12 16:31:37.463985]
>>> Thread-1 finished [2012-04-12 16:31:38.421639]

PS: Estou vendo um jeito de ficar melhor colar códigos aqui, aceito sugestões 😉

Deixe um comentário

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google

Você está comentando utilizando sua conta Google. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s

%d blogueiros gostam disto: