Pergunta

O conceito de um coroutine parece muito interessante, mas eu não sei, se ele faz sentido em um ambiente produtivo real? Quais são os casos de uso para co-rotinas, que podem ser resolvidos mais elegante, mais simples ou mais eficiente quanto com outros métodos?

Foi útil?

Solução

coroutines Verdadeiros requerem apoio de seu ferramental - eles precisam ser implementados pelo compilador e apoiado pela estrutura subjacente

.

Um exemplo do mundo real de co-rotinas é encontrado com o "retorno rendimento" palavra-chave fornecido em C # 2.0, que permite escrever um método que retorna vários valores para looping.

O "yield return" tem limitações, no entanto -. A implementação usa uma classe auxiliar para o estado de captura, e ele suporta apenas um caso específico de co-rotina como gerador (iterator)

No caso mais geral, a vantagem de co-rotinas é que eles fazem certos cálculos baseados estado muito mais fácil de expressar e mais fácil de entender - implementação de uma máquina de estado como um conjunto de co-rotinas pode ser mais elegante do que as abordagens mais comuns . Mas, fazendo isso requer suporte e ferramentas que ainda não existe no C # ou Java.

Outras dicas

Algumas boas respostas que descrevem o que coroutines são.

Mas para um caso de uso real. Tome um servidor web. Ele tem várias conexões simultâneas, e quer cronograma de leitura e escrita de todos eles.

Isso pode ser implementado utilizando co-rotinas. Cada conexão é uma co-rotina que lê / escreve uma pequena quantidade de dados, então "yields" de controle para o programador, que passa para a próxima co-rotina (que faz a mesma coisa) como nós percorrer todas as conexões disponíveis.

Muitos deles, por exemplo:

grep TODO *.c *.h | wc -l

A tubagem acima é exactamente um co-rotina: o comando grep gera uma sequência de linhas que vão para um tampão, o comando wc "come-los"; se os preenchimentos de buffer, os grep "blocos" até que o esvazia-tampão, e se o buffer está vazio, o comando wc aguarda nova entrada.

A coisa sobre coroutines é que eles são mais frequentemente agora usado em padrões mais restritos, como os geradores de Python mencionado, ou como gasodutos.

Se você quiser olhar mais para eles, ver os artigos da Wikipédia, especialmente na coroutines iterators .

Eu sei que isso é quase 5 anos desde que a pergunta foi feita, mas estou surpreendido ninguém mencionou o caso de uso de jogos, onde co-rotinas são usados ??muito a fatia de tempo essencialmente uma computação.

Para manter uma taxa de quadros consistentes em um jogo, digamos que 60 fps, você tem cerca de 16.6ms para executar código em cada quadro. Que inclui simulação de física, processamento de entrada, desenho / pintura.

Vamos dizer que o seu método é executado em cada frame. Se o seu método leva muito tempo e acaba abrangendo vários quadros, você está indo para descansar cambalear da computação no circuito jogo que resulta em que o usuário vê "Jank" (uma queda súbita na taxa de quadros).

O que coroutines deixar você fazer é de alguma forma fatia de tempo esse cálculo para que seja executada um pouco em cada quadro.

Para que isso aconteça, coroutines essencialmente permite que o método de "rendimento" o cálculo de volta para o "chamador" (neste caso, o loop do jogo) para que a próxima vez que o método é chamado ele retoma a partir de onde parou.

co-rotinas são úteis para implementar padrões de produtor / consumidor.

Por exemplo, Python introduzido coroutines em um recurso de linguagem chamado geradores , que foi destinado a simplificar a implementação de iteradores.

Também pode ser útil para implementar a multitarefa cooperativa, onde cada tarefa é uma co-rotina que os rendimentos para um programador / reator.

coroutines pode ser útil a qualquer momento um sistema tiver dois ou mais pedaços de código cuja representação mais natural seria como uma série sequencial de etapas que envolvem um monte de espera.

Por exemplo, considere um dispositivo que tem uma interface de usuário LCD-e-teclado e um modem, e ele precisa usar o modem para periodicamente ligar e denunciar a sua estatuto independente do que o usuário no teclado está fazendo. A melhor maneira de escrever a interface do usuário pode ser usar funções como "input_numeric_value (& CONV_SPEED_FORMAT, & conveyor_speed);" que irá retornar quando um usuário entrou um valor, e a melhor maneira de lidar com a comunicação pode ser de uso funções como "wait_for_carrier ();" que irá retornar quando a unidade seja ligada ou determinado que não vai.

Sem coroutines, quer o subsistema UI ou o subsistema de modem teria que ser implementado usando uma máquina de estado. Usando coroutines torna possível para ambos os subsistemas a ser escrito no estilo mais natural. Note-se que é importante que nem subsistema nunca vai muito tempo sem colocar as coisas em um estado "consistente" e chamando yield (), nem chama yield () sem colocar as coisas em um estado "consistente" em primeiro lugar, mas geralmente não é difícil encontrar aqueles restrições.

Note que, enquanto um poderia usar full-blown multitarefa, que requer o uso de bloqueios em todo o lugar qualquer estado do tempo compartilhado é alterada. Desde o switcher coroutine nunca vai mudar as coisas, exceto no yield () chamadas, seja de rotina pode livremente alterar o estado compartilhado tanto tempo, pois garante que tudo em ordem antes da próxima rendimento, e está preparado para a outra rotina para estado alter " durante" o rendimento ().

Como um exemplo mais específico-in o produtor / linha de consumo, algo tão simples como o programa de relatórios lote humilde poderia realmente usar co-rotinas.

O dica chave para esse exemplo é ter um trabalho não trivial para consumir dados de entrada (por exemplo, a análise de dados ou acumular cargas e pagamentos por uma conta), e o trabalho não trivial para produzir a saída. Quando você tem essas características:

  • É fácil de organizar / entender o código do lado de entrada, se puder "Emit" unidades de trabalho em vários lugares.
  • É igualmente fácil de organizar / entender o código do lado de saída se ele pode "agarrar" a próxima unidade de trabalho em uma estrutura de controle aninhado.

Em seguida, co-rotinas e as filas são ambas as técnicas bom ter à sua disposição.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top