- 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 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:
- Use o decorador
- multithreading uso básico
- 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
, 数据库IO
e 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 sleep
para 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