O que é uma corotina?

204

O que é uma corotina? Como eles estão relacionados à simultaneidade?

yesraaj
fonte
2
O código simultâneo não precisa necessariamente ser executado em "paralelo" (não vamos introduzir novos termos).
Lucid_dreamer 30/01
2
Eu escrevi uma biblioteca de corotina com o padrão C, suportando mensagens select / poll / eplll / kqueue / iocp / Win GUI para Linux, BSD e Windows. É um projeto de código aberto em github.com/acl-dev/libfiber . O conselho será bem vindo.
ShuXin Zheng 24/02
Mais informações interessantes aqui: stackoverflow.com/q/16951904/14357
spender
Eu posso imaginar que esta pergunta será reduzida se for feita na era atual. Não sabe ao certo por que existe tanta diferença na percepção da comunidade em comparação com antes?
tnkh 23/05/19
uma corotina é uma função que pode suspender sua execução antes de atingir o retorno e indiretamente pode passar o controle para outra corotina por algum tempo.
hassanzadeh.sd

Respostas:

138

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á.

user21714
fonte
19
Qual é a diferença entre chamar uma função diretamente e produzir a partir de uma corotina ao envolver essa função nessa corotina?
Ming Li
3
Talvez seja melhor explicar que esses dois conceitos não são realmente "ortogonais" nesse contexto. Você pode definitivamente definir como os dois conceitos são semelhantes entre si. A idéia de passar o controle entre duas ou mais coisas é muito semelhante.
steviejay
8
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.
Adam Arold
@steviejay orthogonal = Not similar to each other?
tonix
1
@tonix me disseram que orthogonalsignifica "independente um do outro".
Rick
77

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 .

Nan Xiao
fonte
6
As corotinas não são executadas independentemente. Eles se revezam, cada um esperando o outro fazer parte do trabalho. Eles se coordenam ativamente entre si. Esse é o oposto da definição de simultaneidade de Rob Pikes.
Erick G. Hagstrom
2
@ ErickG.Hagstrom: Embora eles não sejam executados de forma independente, a lógica de todas as rotinas pode ser independente, certo? Se estiver certo, é como um sistema operacional preventivo em execução na CPU de um núcleo, um processo deve abandonar a CPU para permitir que outras tarefas sejam executadas.
Nan Xiao
6
Há uma diferença entre abandonar a CPU para permitir que outra tarefa seja executada e dizer a algum outro processo específico que é hora de executar. As corotinas fazem o último. Isso não é independente em nenhum sentido.
Erick G. Hagstrom
7
@ChrisClark Eu concordo com você. Corotinas são simultâneas. Aqui estão algumas citações da wikipedia: As corotinas são muito semelhantes às threads. No entanto, as corotinas são multitarefas cooperativamente, enquanto os threads geralmente são multitarefas preemptivamente. Isso significa que eles fornecem simultaneidade, mas não paralelismo .
smwikipedia
3
E: multitarefa cooperativa, também conhecida como multitarefa não preventiva, é um estilo de multitarefa de computador no qual o sistema operacional nunca inicia uma troca de contexto de um processo em execução para outro processo. Em vez disso, os processos voluntariamente geram controle periodicamente ou quando ociosos ou logicamente bloqueados para permitir que vários aplicativos sejam executados simultaneamente.
smwikipedia
47

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.

mr1031011
fonte
6
Ilustração muito simples e direta. +1 para isso.
Taslim Oseni 02/01/19
ótima ilustração. Eu construí uma história semelhante - com a fila esperando para coletar um pacote. mas hoje, a sua é muito mais realista, quem fica na fila quando há entregas door2door? Lol
apolak
1
Essa é uma explicação incrível. Da própria citação, é super claro.
Farruh Habibullaev 19/06/19
15

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

Cintilação
fonte
Não é tão parecido com os threads - que são executados independentemente e simultaneamente (núcleos separados em paralelo). Além disso, a comparação da sub-rotina falha no sentido de que existem vários caminhos de execução independentes e eles não estão retornando resultados um para o outro.
javadba 24/03
11
  • Coroutines são ótimos recursos disponíveis no Kotlin Language
  • As corotinas são uma nova maneira de escrever código assíncrono e sem bloqueio (e muito mais)
  • Corotina são fios leves. Um encadeamento leve significa que ele não é mapeado no encadeamento nativo; portanto, não requer troca de contexto no processador, para que sejam mais rápidos.
  • não mapeia no segmento nativo
  • As corotinas e os segmentos são multitarefa. Mas a diferença é que os threads são gerenciados pelo sistema operacional e as corotinas pelos usuários.

Basicamente, existem dois tipos de corotinas:

  1. Stackless
  2. Stackful

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

Dhaval Jivani
fonte
1
Boa resposta! Útil para desenvolvedores Kotlin e Android.
Malwinder Singh 6/04
5

Em uma observação diferente, na geventbiblioteca python há uma coroutinebiblioteca de rede baseada em recursos que fornece recursos semelhantes a threads, como solicitações de rede assíncronas, sem a sobrecarga de criar e destruir threads. A coroutinebiblioteca usada é greenlet.

Joseph
fonte
2

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.

Das corotinas (C ++ 20)

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.

Shihe Zhang
fonte
1

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

Exemplo 1 Exemplo2

BoraKurucu
fonte
1

Acho que uma explicação desse link é bastante direta. Nenhuma dessas respostas tenta explicar simultaneidade x paralelismo, exceto o último marcador desta resposta .

  1. o que é concorrente (programa)?

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.

  1. corotina e simultaneidade

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?

insira a descrição da imagem aqui

Como mostra a foto, não é necessário ligar returnpara 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.

Izana
fonte
0

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 pythonbiblioteca 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 i7núcleos hyperthread são utilizados: você pode ver 797% de utilização em Activity Monitoror Top. Em vez disso, ao executar um pythonprograma típico - mesmo com coroutinesou python threading- a utilização atingirá o máximo de 100%. Ou seja, uma máquina hyperthread.

javadba
fonte