Tutorial avançado de PHP - como jogar a co-rotina do PHP? Este artigo irá guiá-lo através da co-rotina do swoole

As corrotinas são complexas e não complicadas, mas difíceis e não difíceis.Uma frase pode ser resumida: pode melhorar a simultaneidade, mas não pode acelerar as tarefas, o código síncrono implementa IO assíncrono e blocos de código não bloqueantes assíncronos.

Uma co-rotina é uma função especial, uma função que pode ser suspensa e, em seguida, retomar a execução de onde foi suspensa.Múltiplas co-rotinas em uma thread são seriais, assim como o processo de processamento da CPU. Uma co-rotina pode ser executada em um thread, a menos que o controle seja dado a outras co-rotinas para executar. A co-rotina não pode usar a CPU multi-core, portanto, a co-rotina só pode resolver o problema de simultaneidade, não o problema de velocidade de processamento da tarefa. Uma corrotina é dividir uma grande tarefa em fragmentos menores e encapsular uma função do processo. Quando uma das corrotinas precisa ser bloqueada por IO, ela suspende ativamente a corrotina atual e transfere o controle para outras corrotinas para execução.

Sabemos que processos e threads são programados pelo sistema operacional. Quando executar depende de quando o sistema operacional dá tempo de CPU para um processo ou thread, e quando a co-rotina entrega o controle é determinado pelo usuário. Os processos e threads pertencem ao modo kernel e as corrotinas pertencem aos threads do modo de usuário.

A co-rotina é uma thread leve no modo de usuário, e a programação da co-rotina é totalmente controlada pelo usuário. A co-rotina tem seu próprio contexto de registro e pilha. Quando a co-rotina estiver programada para alternar, salve o contexto de registro e empilhe para outros lugares. Ao alternar de volta, restaure o contexto de registro salvo anteriormente e a pilha. Operar diretamente a pilha basicamente não terá sobrecarga de comutação central e você pode acessar variáveis ​​globais sem bloqueio. , Portanto, a mudança de contexto é muito rápida.

Meus pinguins trocam oh juntos

Recursos de co-rotina

  • Threads de modo de usuário, ao encontrar IO, ativamente desistem do controle

  • Vários códigos de co-rotina ainda são seriais, não há necessidade de bloquear

  • Baixa sobrecarga, ocupa apenas memória, nenhum processo e sobrecarga de troca de thread

  • Grande quantidade de simultaneidade, um único processo pode abrir corrotinas de 50w

  • A qualquer hora, em qualquer lugar, contanto que você queira simultaneidade, chame go para criar uma co-rotina

Insira a descrição da imagem aqui

Sabemos que os threads são processos leves, então as corrotinas são threads leves. As corrotinas são executadas em roscas e uma rosca pode ter várias corrotinas.

Sabemos que quando o processo encontra bloqueio, mais uma thread é aberta para alternar dentro do processo para evitar a alternância do processo todas as vezes, de forma que o tempo disponível alocado pela CPU para o processo possa ser usado com mais vigor. A relação entre uma co-rotina e uma linha e um processo é muito semelhante, exceto que uma co-rotina tem uma relação direta com uma linha.

Insira a descrição da imagem aqui

A figura acima é um diagrama esquemático de alternância entre vários threads, então vamos considerar, se um thread está apenas esperando por operações de E / S (rede ou arquivo), então por que você reutiliza este thread como um thread reutiliza um processo? Vamos remover o IO e ver como é o gráfico.

Insira a descrição da imagem aqui

Remova a parte IO da operação, pode-se ver que basicamente este código de aplicativo de solicitação simultânea pode ser executado em um único encadeamento e a co-rotina aproveita ao máximo o tempo que o encadeamento espera por IO, para que o programa possa executar outros códigos de negócios enquanto espera por IO.

Insira a descrição da imagem aqui

Ele se parece com o fluxo de execução de um encadeamento? Este é o charme de uma co-rotina. Quando uma co-rotina é produzida, ela será suspensa e o controle será transferido para outras co-rotinas dentro do encadeamento porque é executado no encadeamento. Comutação, portanto, a sobrecarga é muito menor do que processos e threads.

Insira a descrição da imagem aqui

Quando o programa chama a co-rotina, a co-rotina atual cederá ativamente o controle para outras co-rotinas no mesmo thread para processamento. Conforme mostrado na figura, quando o código do desenvolvedor precisar usar IO, ele abrirá mão ativamente do controle da co-rotina Usado por outras corrotinas.

Insira a descrição da imagem aqui

Remova a parte IO e observe o processamento da co-rotina. Tudo o que é executado diretamente é a lógica de negócios, evitando que o IO faça com que o thread passe para o estado de espera e aproveitando ao máximo o tempo de execução alocado pela CPU para este thread.

Nota: A co-rotina não acelera as tarefas, ela só pode executar mais tarefas.

Como as corrotinas são construídas em threads, não há como usar as vantagens da CPU multi-core. As corrotinas são adequadas para cenários de computação com IO intensivo.

Qual é o papel das corrotinas?

A co-rotina é aumentar o uso da CPU e evitar um grande número de troca de contexto de thread quando o thread está bloqueado.

echo "1-start\n";
sleep(1);
echo "1-end\n";
echo "2-start\n";
sleep(1);
echo "2-end\n";
echo "3-start\n";
sleep(1);
echo "3-end\n";
echo "4-start\n";
sleep(1);
echo "4-end\n";

Insira a descrição da imagem aqui

O uso da CPU do código acima é de apenas 1%

Swoole\Runtime::enableCoroutine(true);
go(function () {
    
    
    echo "go1-start\n";
    sleep(1);
    echo "go1-end\n";
});
go(function () {
    
    
    echo "go2-start\n";
    sleep(1);
    echo "go2-end\n";
});
go(function () {
    
    
    echo "go3-start\n";
    sleep(1);
    echo "go3-end\n";
});
go(function () {
    
    
    echo "go4-start\n";
    sleep(1);
    echo "go4-end\n";
});

Insira a descrição da imagem aqui

Usando a co-rotina, a taxa de uso da CPU foi aumentada com sucesso para 4%, de forma que a CPU não precisa ficar ociosa para bloqueio de E / S ou realizar troca de contexto. Não disse que as corrotinas não podem ser aceleradas? Depois de usar a co-rotina aqui, por que ela é executada em mais de 1 segundo, o que é diferente do código anterior? O tempo obtido aqui depende da hora em que termina a última execução da co-rotina.

A ordem de execução da co-rotina

Swoole\Runtime::enableCoroutine(true);
go(function(){
    
    
   sleep(2);
   echo "go1\n";
});
go(function(){
    
    
    sleep(1);
    echo "go2\n";
});
echo "main\n";

Primeira saída: main-> go2-> go1

Comunicação entre co-rotinas

A comunicação entre várias co-rotinas é realizada pelo Channel, e várias co-rotinas ajudam na conclusão de tarefas comuns.

Swoole\Runtime::enableCoroutine(true);
$chan = new Swoole\Coroutine\Channel();
go(function () use ($chan){
    
    
    sleep(1);
    $chan->push(['name'=>'sunny']);
});

go(function() use ($chan){
    
    
    $data = $chan->pop();
    print_r($data);
});
echo "结束\n";

Combate real: realize a função waitGroup

Use o canal fornecido por Swoole para implementar um waitGroup, a função principal é aguardar a conclusão de todas as corrotinas.

<?php
class WaitGroup{
    
    
    private $count;
    private $chan;
    public function __construct()
{
    
    
        $this->chan = new Swoole\Coroutine\Channel();
    }

    public function add(){
    
    
        $this->count++;
    }
    public function done(){
    
    
        $this->chan->push(true);
    }

    public function wait(){
    
    
        for($i=0;$i<$this->count;$i++){
    
    
            $this->chan->pop();
        }
    }

}

<?php
include 'waitgroup.php';
Swoole\Runtime::enableCoroutine(true);
echo "start".PHP_EOL;
$t = microtime(true);
go(function() use ($t){
    
    
    $wg = new WaitGroup();
    $wg->add();
    go(function() use ($t,&$wg){
    
    
        echo file_get_contents("https://www.sunnyos.com/swoole.php");
        echo "协程1:".(microtime(true)-$t).PHP_EOL;
        $wg->done();
    });
    $wg->add();
    go(function() use ($t,&$wg){
    
    
        echo file_get_contents("https://www.sunnyos.com/swoole.php");
        echo "协程2:".(microtime(true)-$t).PHP_EOL;
        $wg->done();
    });
    $wg->add();
    go(function() use ($t,&$wg){
    
    
        echo file_get_contents("https://www.sunnyos.com/swoole.php");
        echo "协程3:".(microtime(true)-$t).PHP_EOL;
        $wg->done();
    });
    $wg->wait();
    echo '全部结束:'.(microtime(true)-$t).PHP_EOL;
});
echo "end".PHP_EOL;
echo microtime(true)-$t.PHP_EOL;

No código: https://www.sunnyos.com/swoole.php código swoole.php

<?php
sleep(1);
echo "My name is Sunny\n";

Solicitação de rede de simulação de vacina inativa demorada

Insira a descrição da imagem aqui

Aqui está uma olhada nas três goroutines usadas para fazer solicitações de rede. Cada solicitação leva 1 segundo, mas quando as três solicitações são executadas aqui, leva apenas 1,2 segundos para executar, mas a taxa de uso da CPU é 6 %, isso mostra que a co-rotina usa totalmente a cpu.

Preste atenção, não se perca

Tudo bem, pessoal, o acima é todo o conteúdo deste artigo. As pessoas que podem ver aqui são todos talentos . Como eu disse antes, há muitos pontos técnicos em PHP, porque são muitos, é realmente impossível escrever, e você não vai ler muito depois de escrever, então irei organizá-los em PDF e documentos aqui, se necessário lata

Clique para inserir o código secreto: PHP + 「Plataforma」

Insira a descrição da imagem aqui

Insira a descrição da imagem aqui


Para obter mais conteúdo de aprendizado, você pode visitar o Catálogo [Comparative Standard Factory] de Tutoriais de Excelente PHP Architect, contanto que você possa lê-lo para garantir que o salário suba um nível (atualização contínua)

O conteúdo acima espera ajudar a todos . Muitos PHPers sempre encontram alguns problemas e gargalos quando são avançados. Não há nenhum senso de direção ao escrever muito código comercial. Não sei por onde começar a melhorar. Compilei algumas informações sobre isso, incluindo Mas não se limitando a: arquitetura distribuída, alta escalabilidade, alto desempenho, alta simultaneidade, ajuste de desempenho do servidor, TP6, laravel, YII2, Redis, Swoole, Swoft, Kafka, otimização Mysql, scripts de shell, Docker, microsserviços, Nginx etc. Muitos pontos de conhecimento, produtos secos avançados avançados, podem ser compartilhados com todos gratuitamente, e aqueles que precisam podem se juntar ao meu grupo de intercâmbio de tecnologia PHP

Acho que você gosta

Origin blog.csdn.net/weixin_49163826/article/details/109189754
Recomendado
Clasificación