1, Python programação concorrente a partir de uma perspectiva de desempenho Na programação concorrente

  • prefácio
  • O conceito básico de programação concorrente
  • VS VS de segmento único de multi-processo multi-threaded
  • Comparação de desempenho Resumo dos resultados

prefácio

Como um ramo da Série Avançada 并发编程"" Eu acho que isso é cada programador deve estar em.

并发编程 Esta série, eu me preparei por quase uma semana, penteando o conhecimento, a pensar o que você quer para citar um exemplo, a fim de mais entender completamente esse conhecimento faz com que seja mais fácil de detectar. Esperança de que a apresentação dos resultados realmente como imaginado, também amigável para branco.

Ontem cerca de terminar esta série eu provavelmente diria o seguinte (este último pode ajustar):

Esboço do cursoEsboço do curso

Para programação concorrente, implementações Python, resumiu o que, mais ou menos as três seguintes maneiras:

  • multithreading
  • Multi-processo
  • Co-rotina (gerador)

Nos capítulos seguintes, estaremos após o outro para dizer sobre estes três pontos do conhecimento.

O conceito básico de programação concorrente

Antes de começar a explicar a teoria do conhecimento, tinha uma olhada em alguns conceitos básicos. Embora seja curso avançado, mas eu também quero escrever mais branco, mais user-friendly.

串行: Uma pessoa, ao mesmo tempo só pode fazer uma coisa, como depois do jantar para assistir televisão;
并行: um homem no mesmo período de tempo pode ser mais ou coisa, por exemplo, você pode comer enquanto assiste TV;

Em Python, 多线程 e  协程 embora a rigor é uma série, mas maior do que a eficiência média da implementação do programa de série muito.
Programa de série geral, quando o programa bloqueado e só posso esperar, não posso fazer outras coisas. Como, foi ao ar no drama de TV, para o tempo de publicidade, não podemos tirar proveito de tempo de publicidade para comer uma refeição. Para o programa, esta é claramente uma eficiência muito baixa, não é razoável.

É claro que, após a conclusão deste curso, entendemos que o uso de tempo de publicidade para fazer outras coisas, horário flexível. É por isso que nós 多线程e 协程 você quiser nos ajudar a realizar coisas, tarefas de gestão racionais internos, fazendo com que a máxima eficiência do programa.

Embora  多线程 e  协程 muito inteligente. Mas ainda não é suficiente eficiente, deve ser a multitarefa mais eficiente, comer enquanto assiste televisão conversando. Esta é a nossa  多进程 capacidade de fazer as coisas.

Para ajudar você a entender melhor o mais intuitivo para encontrar as duas imagens na Internet, para explicar vividamente a diferença entre multi-processo multi-threaded e. (Invasão excluído)

  • 多线程Alternadamente executado, o serial num outro significado.

  • 多进程, Em paralelo, em simultâneo, no verdadeiro sentido.

. VS de segmento único de multi-processo multi-threaded VS

Texto sempre pálido, não tão bom quanto mil palavras algumas linhas de código vêm Kongwuyouli.

Primeiro de tudo, a configuração do ambiente de teste é o seguinte

sistema operacional O número de núcleos de CPU Memória (G) disco rígido
CentOS 7.2 24 nuclear 32 disco rígido mecânico

Note que
o código a seguir, compreender, ter o conhecimento de que os pontos brancos:

  1. Use o decorador
  2. multithreading uso básico
  3. O uso de base de múltiplos processos

Claro, não entendo isso não importa, a conclusão principal, permitir que todos, multi-processo multi-threaded ter uma compreensão clara do efeito geral sobre a realização do single-threaded, para conseguir este efeito, a missão deste artigo é concluído, espera até o último , aprender a série completa, pode querer voltar ao redor e entender que pode haver uma compreensão mais profunda.

Vejamos, single-threaded, multi-threaded e multi-processo, seja forte ou fraco em operação.

Antes de começar a comparar, primeiro definir quatro tipos de cenários

  • computação de CPU
  • IO de disco intensivo
  • rede IO-intensiva
  • IO analógica intensiva []

Por que esses tipos de cenários, e isso 多线程 多进程se aplica a uma cena. Em conclusão, deixe-me explicar.

# CPU计算密集型
def count(x=1, y=1):
    # 使程序完成150万计算
    c = 0
    while c < 500000:
        c += 1
        x += x
        y += y


# 磁盘读写IO密集型
def io_disk():
    with open("file.txt", "w") as f:
        for x in range(5000000):
            f.write("python-learning\n")


# 网络IO密集型
header = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36'}
url = "https://www.tieba.com/"

def io_request():
    try:
        webPage = requests.get(url, headers=header)
        html = webPage.text
        return
    except Exception as e:
        return {"error": e}


# 【模拟】IO密集型
def io_simulation():
    time.sleep(2)

indicadores de concorrência, usamos o tempo para considerar. Quanto menos tempo gasto, maior a eficiência.

Por conveniência, faz o olhar código mais conciso, eu estou aqui é para definir um simples  时间计时器 decorador.
Se você não está muito a compreensão do decorador, não importa, contanto que você sabe o que é usado para calcular em função do tempo nele.

def timer(mode):
    def wrapper(func):
        def deco(*args, **kw):
            type = kw.setdefault('type', None)
            t1=time.time()
            func(*args, **kw)
            t2=time.time()
            cost_time = t2-t1
            print("{}-{}花费时间:{}秒".format(mode, type,cost_time))
        return deco
    return wrapper

O primeiro passo, dar uma olhada em single-threaded

@timer("【单线程】")
def single_thread(func, type=""):
    for i in range(10):
              func()

# 单线程
single_thread(count, type="CPU计算密集型")
single_thread(io_disk, type="磁盘IO密集型")
single_thread(io_request,type="网络IO密集型")
single_thread(io_simulation,type="模拟IO密集型")

Olhe para os resultados

【单线程】-CPU计算密集型花费时间:83.42633867263794秒
【单线程】-磁盘IO密集型花费时间:15.641993284225464秒
【单线程】-网络IO密集型花费时间:1.1397218704223633秒
【单线程】-模拟IO密集型花费时间:20.020972728729248秒

O segundo passo, ver os multi-threaded

@timer("【多线程】")
def multi_thread(func, type=""):
    thread_list = []
    for i in range(10):
        t=Thread(target=func, args=())
        thread_list.append(t)
        t.start()
    e = len(thread_list)

    while True:
        for th in thread_list:
            if not th.is_alive():
                e -= 1
        if e <= 0:
            break

# 多线程
multi_thread(count, type="CPU计算密集型")
multi_thread(io_disk, type="磁盘IO密集型")
multi_thread(io_request, type="网络IO密集型")
multi_thread(io_simulation, type="模拟IO密集型")

Olhe para os resultados

【多线程】-CPU计算密集型花费时间:93.82986998558044秒
【多线程】-磁盘IO密集型花费时间:13.270896911621094秒
【多线程】-网络IO密集型花费时间:0.1828296184539795秒
【多线程】-模拟IO密集型花费时间:2.0288875102996826秒

O terceiro passo é olhar para o último multi-processo

@timer("【多进程】")
def multi_process(func, type=""):
    process_list = []
    for x in range(10):
        p = Process(target=func, args=())
        process_list.append(p)
        p.start()
    e = process_list.__len__()

    while True:
        for pr in process_list:
            if not pr.is_alive():
                e -= 1
        if e <= 0:
            break

# 多进程
multi_process(count, type="CPU计算密集型")
multi_process(io_disk, type="磁盘IO密集型")
multi_process(io_request, type="网络IO密集型")
multi_process(io_simulation, type="模拟IO密集型")

Olhe para os resultados

【多进程】-CPU计算密集型花费时间:9.082211017608643秒
【多进程】-磁盘IO密集型花费时间:1.287339448928833秒
【多进程】-网络IO密集型花费时间:0.13074755668640137秒
【多进程】-模拟IO密集型花费时间:2.0076842308044434秒

comparação de desempenho do resumo dos resultados

Os resultados estão resumidos isso, tabulados.

espécies computação de CPU IO de disco intensivo rede IO-intensiva Analógico IO-intensiva
Single-threaded 83.42 15,64 1.13 20.02
multithreading 93,82 13,27 0,18 2,02
Multi-processo 9,08 1,28 0,13 2.01

Temos de analisar essa forma.

Em primeiro lugar CPU密集型, para comparar multi-threaded single-threaded, não só nenhuma vantagem, aparentemente devido à liberação de bloqueio bloqueio GIL global em curso, comutação tópicos e, ineficiente e multi-processo demorado, porque é mais do que uma CPU nos mesmos cálculos de tempo , o equivalente de pessoas dez fazer o trabalho de um homem, aparentemente, a eficiência está crescendo exponencialmente.

Em seguida, o IO-intensiva, IO密集型pode ser 磁盘IO, 网络IO, 数据库IOe assim por diante, todos pertencem à mesma classe, calcular a quantidade é muito pequena, principalmente um desperdício de tempo para esperar por IO. Através da observação, podemos encontrar o nosso disco IO, rede de dados IO, multi-threaded comparação single-threaded não refletem a grande vantagem. Isto é devido ao IO tarefa de nosso programa não é pesado, então a vantagem não é óbvia.

Então, eu também acrescentou um 模拟IO密集型"" uso sleeppara simular o tempo de espera IO é refletir as vantagens do multi-threading, mas também nos permite uma compreensão mais intuitiva do trabalho processo de multi-threaded. Cada segmento precisa ser um único segmento sleep(2), o segmento é de 10 20s, e multi-threading, em sleep(2)tempo, vai mudar para outro segmento, de modo que 10 threads ao mesmo tempo sleep(2), foi apenas os últimos 10 tópicos 2s.

As seguintes conclusões podem ser tiradas

  • Sempre o mais lento, multi-processo de single-threaded é sempre o mais rápido.
  • Adequado para utilização em multi-threaded cenas IO-intensiva, tais como répteis, desenvolvimento de web sites
  • Adequado para utilização em vários processos nos CPU calcula os cenários operacionais elevadas exigidas, tais como análise de dados grande, aprendizagem máquina
  • Apesar de multi-processo é sempre o, mas não necessariamente a melhor escolha mais rápido, porque exige, a fim de perceber as vantagens de recursos da CPU inferior ao apoio
Publicado 91 artigos originais · ganhou elogios 47 · vê 90000 +

Acho que você gosta

Origin blog.csdn.net/qq_30007885/article/details/102565667
Recomendado
Clasificación