Python multi-threaded, multi-processo, co-rotina! Com o caso explicou, esta onda no lugar!

I. Introdução

Depois de muitas vezes nós escrevemos um réptil, para atingir os requisitos vai encontrar muita coisa para melhorar o lugar, que é muito importante ponto está rastejando velocidade. Este artigo explica como usar o código através do multi-processo, multi-thread, co-rotina para melhorar a velocidade rastreamento. Nota: Nós não insights sobre a teoria e princípio, tudo em seu código.

Em segundo lugar, síncrona

Primeiro, nós escrever uma répteis simplificados, cada segmento funcional, conduta consciente programação funcional. O código seguinte é um objecto 300 Baidu página de acesso e devolver um código de estado, em que a função pode ser ciclos parse_1 conjunto, cada ciclo do número actual ciclo (a partir de 0) e a função de entrada URL parse_2.

solicitações de importação

parse_1 def ():

url = 'https://www.baidu.com'

para i na gama (300):

parse_2 (url)

def parse_2 (url):

= resposta requests.get (URL)

print (response.status_code)

se __name__ == '__main__':

parse_1 ()

Desempenho é consumido principalmente na solicitação IO, quando a URL de solicitação usando o modo single-threaded conduzirá inevitavelmente à espera

O código de amostra é uma lógica de série típico, parse_1 passa URL e o número de ciclos até à parse_2, pedido parse_2 e devolve o estado parse_1 Código continuar a iteração passo foi repetido uma vez antes da

Em terceiro lugar, multi-threaded

Porque existe apenas um segmento de tempo de CPU em cada escala na execução do programa, de modo roscado multi-processo aumenta realmente o uso resultando na melhoria da utilização da CPU

bibliotecas multi-threaded tem um monte de, aqui concurrent.futures em ThreadPoolExecutor para demonstrar. biblioteca Introdução ThreadPoolExecutor porque é mais concisa do que qualquer outro código da biblioteca

Por conveniência de ilustração, o seguinte código se ele é recém-partes acrescentou, a primeira linha de código mais> Símbolo facilitar a observação de ilustração, a necessidade operação real a ser removido

solicitações de importação

> A partir concurrent.futures importação ThreadPoolExecutor

parse_1 def ():

url = 'https://www.baidu.com'

# Criar pool de threads

> Piscina = ThreadPoolExecutor (6)

para i na gama (300):

> Pool.submit (parse_2, url)

> Pool.shutdown (espera = True)

def parse_2 (url):

= resposta requests.get (URL)

print (response.status_code)

se __name__ == '__main__':

parse_1 ()

A sincronização é assíncrono com o parente. Asynchronous é independente um do outro, continuar a fazer sua própria coisa enquanto espera para um evento, você não precisa esperar para este evento após a conclusão da obra. fio Asynchronous é alcançar uma forma, que é o processamento assíncrono meio-threading multi-assíncronos que não sei os resultados, às vezes precisamos de saber os resultados, você pode usar um callback

solicitações de importação

de concurrent.futures ThreadPoolExecutor importação

# Adicionar uma função de retorno

> Def callback (futuro):

> Print (future.result ())

parse_1 def ():

url = 'https://www.baidu.com'

piscina = ThreadPoolExecutor (6)

para i na gama (300):

> Resultados = pool.submit (parse_2, url)

# passos fundamentais Callback

> Results.add_done_callback (callback)

pool.shutdown (espera = True)

def parse_2 (url):

= resposta requests.get (URL)

print (response.status_code)

se __name__ == '__main__':

parse_1 ()

P ython um multi-threaded inúmeras pessoas têm criticado GIL (Global Interpreter Lock), mas pertencem a tarefa de multi-threaded IO-intensiva ainda é muito adequado para rastreamento das páginas deste maioria.

Em quarto lugar, multi-processo

Multi-processo implementado de duas maneiras: ProcessPoolExecutor e multiprocessamento

1. ProcessPoolExecutor

E semelhante ThreadPoolExecutor rosca-multi

solicitações de importação

> A partir concurrent.futures importar ProcessPoolExecutor

parse_1 def ():

url = 'https://www.baidu.com'

# Criar pool de threads

> Piscina = ProcessPoolExecutor (6)

para i na gama (300):

> Pool.submit (parse_2, url)

> Pool.shutdown (espera = True)

def parse_2 (url):

= resposta requests.get (URL)

print (response.status_code)

se __name__ == '__main__':

parse_1 ()

Procure alterações em nome de duas classes, o código ainda é muito simples, empatia também pode adicionar uma função de retorno

solicitações de importação

de concurrent.futures ProcessPoolExecutor importação

> Def callback (futuro):

> Print (future.result ())

parse_1 def ():

url = 'https://www.baidu.com'

piscina = ProcessPoolExecutor (6)

para i na gama (300):

> Resultados = pool.submit (parse_2, url)

> Results.add_done_callback (callback)

pool.shutdown (espera = True)

def parse_2 (url):

= resposta requests.get (URL)

print (response.status_code)

se __name__ == '__main__':

parse_1 ()

2. multiprocessamento

olhar directo sobre o código, tudo nos comentários.

solicitações de importação

> De multiprocessamento importação Piscina

parse_1 def ():

url = 'https://www.baidu.com'

# Piscina construída

> Piscina = Piscina (processos = 5)

# resultados Armazene

> Res_lst = []

para i na gama (300):

# Junte-se à piscina tarefa

> Res = pool.apply_async (func = parse_2, args = (url,))

# Resultado Aquisição concluída (necessidade de remover)

> res_lst.append (res)

# Armazenar o resultado final (também podem ser armazenados diretamente ou impressão)

> Good_res_lst = []

> Para res em res_lst:

# Obter resultados depois de usar o processo de aquisição

> Good_res = res.get ()

# Resultado de julgamento é bom ou ruim

> Se good_res:

> good_res_lst.append (good_res)

# Desligue e aguardar a conclusão

> Pool.close ()

> Pool.join ()

def parse_2 (url):

= resposta requests.get (URL)

print (response.status_code)

se __name__ == '__main__':

parse_1 ()

Você pode ver a biblioteca de código multiprocessamento um pouco entediante, mas suportar mais expansão. Multi-processo e multi-threading pode realmente atingir o objectivo de acelerar, mas se eles estão bloqueando fio IO ou processo será um desperdício, para que haja uma maneira melhor ......

Quinto, assíncrona sem bloqueio

Coroutine + retorno de chamada com dinâmica não-bloqueio colaboração assíncrona podemos alcançar o propósito, a natureza tomou apenas um segmento, de modo a um grande escopo de uso de recursos

Clássico é o uso de assíncrona sem bloqueio asyncio rendimento + biblioteca, a fim de facilitar o uso do surgimento gradual de uma aiohttp pacote mais superior, a fim de melhor compreender a biblioteca asyncio melhor compreensão sem bloqueio assíncrono. E GEvent é um muito fácil de implementar biblioteca coroutine

solicitações de importação

> De macaco importação GEvent

# Alma Macaco patch é executado em colaboração

> Monkey.patch_all ()

> Import vendia

parse_1 def ():

url = 'https://www.baidu.com'

# Criar uma lista de tarefas

> Tasks_list = []

para i na gama (300):

> Task = gevent.spawn (parse_2, url)

> Tasks_list.append (tarefa)

> Gevent.joinall (tasks_list)

def parse_2 (url):

= resposta requests.get (URL)

print (response.status_code)

se __name__ == '__main__':

parse_1 ()

GEvent pode muito a velocidade, também introduz um novo problema: se não quiser rápido demais para causar muita carga sobre o servidor como fazer? Se é um multi-processo de construção de multi-threaded da piscina, você pode controlar o número de piscina. Se você quiser controlar a velocidade com GEvent também tem uma boa abordagem: fila de construção. GEvent também forneceu classe Quene, altere o seguinte código maior

solicitações de importação

de macaco importação GEvent

monkey.patch_all ()

importação vendia

> De importação gevent.queue Queue

parse_1 def ():

url = 'https://www.baidu.com'

= Tasks_list []

# Fila de instanciação

> Quene = Fila ()

para i na gama (300):

Todas as filas pressionado url #

> Quene.put_nowait (url)

fila de dois #

> Para _ na faixa (2):

> Task = gevent.spawn (parse_2)

> Tasks_list.append (tarefa)

gevent.joinall (tasks_list)

# Não precisa passar parâmetros, que estão na fila

> Def parse_2 ():

# Ciclo se a fila está vazia

> Enquanto não quene.empty ():

# Pop fila

> Url = quene.get_nowait ()

= resposta requests.get (URL)

Analisando o status da fila #

> Print (quene.qsize (), response.status_code)

se __name__ == '__main__':

parse_1 ()

conclusão

Estes encontram-se vários método de aceleração comumente usado. Se você estiver interessado pode utilizar módulo de teste do código de tempo determina o tempo de execução. Acelerar o réptil é uma habilidade importante, mas a velocidade é controlada adequadamente trabalhadores répteis bons hábitos, não dar demasiada pressão sobre o servidor, bye ~

Mais diversão Código de caixa grupo aditivo: 850591259

 

Acho que você gosta

Origin www.cnblogs.com/Py1233/p/12652948.html
Recomendado
Clasificación