O que é uma corotina? Como eles estão relacionados à simultaneidade?
O que é uma corotina? Como eles estão relacionados à simultaneidade?
Respostas:
Corotinas e simultaneidade são em grande parte ortogonais. As corotinas são uma estrutura de controle geral em que o controle de fluxo é passado cooperativamente entre duas rotinas diferentes sem retorno.
A declaração 'yield' em Python é um bom exemplo. Cria uma rotina. Quando o 'rendimento' é encontrado, o estado atual da função é salvo e o controle é retornado à função de chamada. A função de chamada pode transferir a execução de volta para a função de retorno e seu estado será restaurado até o ponto em que o 'retorno' foi encontrado e a execução continuará.
Coroutines are a general control structure whereby flow control is cooperatively passed between two different routines without returning.
<- Isso é simultaneidade. A palavra que você está procurando é paralelismo.
orthogonal = Not similar to each other
?
orthogonal
significa "independente um do outro".
Na seção Programação em Lua , " Coroutines
":
Uma corotina é semelhante a um encadeamento (no sentido de multithreading): é uma linha de execução, com sua própria pilha, suas próprias variáveis locais e seu próprio ponteiro de instrução; mas compartilha variáveis globais e principalmente qualquer outra coisa com outras corotinas. A principal diferença entre threads e corotinas é que, conceitualmente (ou literalmente, em uma máquina com multiprocessador), um programa com threads executa vários threads em paralelo. As corotinas, por outro lado, são colaborativas: a qualquer momento, um programa com corotinas está executando apenas uma de suas corotinas e essa corotina em execução só suspende sua execução quando solicita explicitamente a suspensão.
Portanto, o ponto é: as corotinas são "colaborativas". Mesmo no sistema com vários núcleos, há apenas uma rotina em execução a qualquer momento (mas vários threads podem ser executados em paralelo). Não há preferência entre corotinas, a corotina em execução deve abandonar a execução explicitamente.
Para " concurrency
", você pode consultar o slide de Rob Pike :
Simultaneidade é a composição de cálculos de execução independente.
Portanto, durante a execução da corotina A, ela passa o controle para a corotina B. Depois de algum tempo, a corotina B passa o controle de volta para a corotina A. Como existe dependência entre as corotinas, e elas devem ser executadas em conjunto, portanto as duas corotinas não são simultâneas .
Acho a maioria das respostas muito técnicas, mesmo que seja uma pergunta técnica. Tive dificuldade em entender o processo da corotina. Eu meio que entendo, mas não entendo ao mesmo tempo.
Encontrei esta resposta aqui muito útil:
https://dev.to/thibmaek/explain-coroutines-like-im-five-2d9
Para citar Idan Arye:
Para criar sua história, eu colocaria algo assim:
Você começa a assistir o desenho animado, mas é a introdução. Em vez de assistir à introdução, você muda para o jogo e entra no lobby online - mas ele precisa de 3 jogadores e apenas você e sua irmã estão nele. Em vez de esperar que outro jogador se junte a você, mude para a lição de casa e responda à primeira pergunta. A segunda pergunta tem um link para um vídeo do YouTube que você precisa assistir. Você abre - e ele começa a carregar. Em vez de esperar o carregamento, você volta ao desenho animado. A introdução terminou, para que você possa assistir. Agora existem comerciais - mas enquanto isso, um terceiro jogador entrou para que você mude para o jogo E assim por diante ...
A idéia é que você não apenas alterne as tarefas com muita rapidez para parecer que está fazendo tudo de uma vez. Você utiliza o tempo que está esperando que algo aconteça (IO) para fazer outras coisas que exigem sua atenção direta.
Definitivamente, verifique o link, há muito mais que não posso citar tudo.
A corotina é semelhante à sub-rotina / threads. A diferença é que, quando um chamador invoca uma sub-rotina / threads, ele nunca retorna à função de chamador. Mas uma corotina pode retornar ao chamador depois de executar alguns trechos de código, permitindo que o chamador execute parte de seu próprio código e volte ao ponto da corotina onde parou a execução e continue a partir daí. ie Uma corotina possui mais de um ponto de entrada e saída
Basicamente, existem dois tipos de corotinas:
O Kotlin implementa corotinas sem pilha - significa que as corotinas não têm pilha própria e, portanto, não são mapeadas no encadeamento nativo.
Estas são as funções para iniciar a rotina:
launch{}
async{}
Você pode aprender mais aqui:
https://www.kotlindevelopment.com/deep-dive-coroutines/
https://blog.mindorks.com/what-are-coroutines-in-kotlin-bf4fecd476e9
Do Python Coroutine :
A execução de corotinas do Python pode ser suspensa e retomada em muitos pontos (consulte corotina). Dentro do corpo de uma função de rotina, os identificadores de espera e assíncrona se tornam palavras-chave reservadas; aguarde expressões, assíncrono para e assíncrono com só pode ser usado em corpos de função de corotina.
Uma corotina é uma função que pode suspender a execução para ser retomada posteriormente . As corotinas não têm pilha: elas suspendem a execução retornando ao chamador. Isso permite que o código sequencial seja executado de forma assíncrona (por exemplo, para lidar com E / S sem bloqueio sem retornos de chamada explícitos), e também suporta algoritmos em sequências infinitas computadas preguiçosamente e outros usos.
Compare com a resposta de outras pessoas:
Na minha opinião, a parte posterior retomada é a principal diferença, assim como a @ Twinkle's.
Embora muitos campos do documento ainda estejam em andamento, essa parte é semelhante à maioria das respostas, exceto as de @Nan Xiao.
As corotinas, por outro lado, são colaborativas: a qualquer momento, um programa com corotinas está executando apenas uma de suas corotinas e essa corotina em execução só suspende sua execução quando solicita explicitamente a suspensão.
Como é citado em Program in Lua, talvez seja relacionado à linguagem (não familiarizado com Lua atualmente), nem todos os documentos mencionaram a única parte.
A relação com o concorrente:
existe uma parte "Execução" das corotinas (C ++ 20). É muito tempo para citar aqui.
Além dos detalhes, existem vários estados.
When a coroutine begins execution
When a coroutine reaches a suspension point
When a coroutine reaches the co_return statement
If the coroutine ends with an uncaught exception
When the coroutine state is destroyed either because it terminated via co_return or uncaught exception, or because it was destroyed via its handle
como o comentário de @Adam Arold na resposta de @ user217714. É simultaneidade.
Mas é diferente de multithreading.
de std :: thread
Threads permitem que várias funções sejam executadas simultaneamente. Os encadeamentos iniciam a execução imediatamente após a construção do objeto de encadeamento associado (pendente de qualquer atraso de agendamento do SO), iniciando na função de nível superior fornecida como argumento do construtor. O valor de retorno da função de nível superior é ignorado e, se finalizar lançando uma exceção, std :: terminate será chamado. A função de nível superior pode comunicar seu valor de retorno ou uma exceção ao chamador via std :: promessa ou modificando variáveis compartilhadas (que podem exigir sincronização, consulte std :: mutex e std :: atomic)
Como é simultânea, funciona como multithreading, especialmente quando a espera é inevitável (da perspectiva do sistema operacional), é também por isso que é confusa.
Uma corotina é um tipo especial de subprograma. Em vez da relação mestre-escravo entre um chamador e um subprograma chamado que existe com os subprogramas convencionais, o chamador e as corotinas chamadas são mais equitativas.
Uma corotina é um subprograma que possui várias entradas e as controla - suportado diretamente em Lua
Também chamado de controle simétrico: o chamador e as corotinas chamadas são mais iguais
Uma chamada de rotina é chamada de currículo
O primeiro resumo de uma corotina está no início, mas as chamadas subseqüentes entram no ponto logo após a última instrução executada na corotina
As corotinas se repetem repetidamente, possivelmente para sempre
As corotinas fornecem execução quase simultânea de unidades de programa (as corotinas); sua execução é intercalada, mas não se sobrepõe
Acho que uma explicação desse link é bastante direta. Nenhuma dessas respostas tenta explicar simultaneidade x paralelismo, exceto o último marcador desta resposta .
citado na "programação Erlang", de Joe Armstrong, o lendário:
um programa simultâneo pode ser executado potencialmente mais rápido em um computador paralelo.
um programa simultâneo é um programa escrito em uma linguagem de programação simultânea. Escrevemos programas concorrentes por razões de desempenho, escalabilidade ou tolerância a falhas.
uma linguagem de programação simultânea é uma linguagem que possui construções explícitas de linguagem para escrever programas simultâneos. Essas construções são parte integrante da linguagem de programação e se comportam da mesma maneira em todos os sistemas operacionais.
um computador paralelo é um computador que possui várias unidades de processamento (CPUs ou núcleos) que podem ser executados ao mesmo tempo.
Portanto, simultaneidade não é o mesmo que paralelismo. Você ainda pode gravar programas simultâneos em um computador de núcleo único. O agendador de compartilhamento de tempo fará com que você sinta que seu programa está sendo executado simultaneamente.
O programa simultâneo tem o potencial de ser executado em paralelo em um computador paralelo, mas não é garantido . O SO pode fornecer apenas um núcleo para executar seu programa.
Portanto, simultaneidade é um modelo de software de um programa simultâneo que não significa que seu programa possa ser executado em paralelo fisicamente.
A palavra “rotina” é composta por duas palavras: “co” (cooperativa) e “rotinas” (funções).
uma. consegue simultaneidade ou paralelismo?
Para ser simples, vamos discuti-lo em um computador de núcleo único .
A simultaneidade é alcançada por compartilhamentos de tempo do SO. Um encadeamento executa seu código em seus intervalos de tempo atribuídos no núcleo da CPU. Pode ser antecipado pelo sistema operacional. Também pode gerar controle para o sistema operacional.
Uma corotina, por outro lado, fornece controle para outra corotina dentro do encadeamento, não para o SO. Portanto, todas as corotinas em um encadeamento ainda exploram o prazo para esse encadeamento sem render o núcleo da CPU para outros encadeamentos gerenciados pelo sistema operacional.
Portanto, você pode pensar que a corotina atinge compartilhamentos de tempo pelo usuário e não pelo SO (ou quase-paralelismo). As corotinas são executadas no mesmo núcleo atribuído ao encadeamento que executa essas corotinas.
Coroutine alcança o paralelismo? Se for código vinculado à CPU, não. Como compartilhamentos de tempo, você sente que eles são executados em paralelo, mas suas execuções são intercaladas e não se sobrepõem. Se for vinculado a IO, sim, ele alcança paralelo por hardware (dispositivos de IO) e não pelo seu código.
b. a diferença com a chamada de função?
Como mostra a foto, não é necessário ligar return
para mudar de controle. Pode render sem return
. Uma corotina salva e compartilha o estado no quadro de função atual (pilha). Portanto, é muito mais leve que a função, pois você não precisa salvar registros e variáveis locais para empilhar e rebobinar a pilha de chamadas quando call ret
.
Expandirei a resposta de @ user21714. Corotinas são caminhos independentes de execução que não podem ser executados simultaneamente. Eles dependem de um controlador - por exemplo, uma python
biblioteca de controladores - para lidar com a alternância entre esses caminhos. Mas para que isso funcione, as próprias corotinas precisam invocaryield
estruturas semelhantes que permitam que sua execução seja pausada.
Em vez disso, os encadeamentos estão sendo executados em recursos de computação independentes e em paralelo. Como eles possuem recursos diferentes, não há necessidade de chamar yield para permitir que os outros caminhos de execução prossigam.
Você pode ver esse efeito iniciando um programa multihreaded - por exemplo, um jvm
aplicativo - no qual todos os oito core i7
núcleos hyperthread são utilizados: você pode ver 797% de utilização em Activity Monitor
or Top
. Em vez disso, ao executar um python
programa típico - mesmo com coroutines
ou python threading
- a utilização atingirá o máximo de 100%. Ou seja, uma máquina hyperthread.