Scripts e gerenciamento de processos com vários threads na linha de comando

Scripts e gerenciamento de processos com vários threads na linha de comando

As coisas que você pode fazer usando scripts bash são ilimitadas. Depois de começar a desenvolver scripts avançados, em breve você descobrirá que começará a encontrar limites de sistema operacional. Por exemplo, seu computador possui 2 threads da CPU ou mais (muitas máquinas modernas têm 8-32 threads)? Nesse caso, você provavelmente se beneficiará de scripts e codificação com vários threads. Continue lendo e descubra o porquê!

Neste tutorial, você aprenderá:

  • Como implementar as frases de um bash com vários threaded diretamente da linha de comando
  • Por que a codificação multithread quase sempre pode e aumentará o desempenho de seus scripts
  • Como os processos de fundo e primeiro plano funcionam e como manipular as filas de emprego
Scripts e gerenciamento de processos com vários threads

Requisitos de software e convenções usadas

Requisitos de software e convenções de linha de comando Linux
Categoria Requisitos, convenções ou versão de software usada
Sistema Independente da distribuição, dependente da versão Bash
Programas Interface da linha de comando Bash (Bash)
Convenções # - requer que os comandos Linux sejam executados com privilégios root diretamente como usuário root ou por uso de sudo comando
$ - Requer que os comandos do Linux sejam executados como um usuário não privilegiado regular

Quando você executa um script de bash, ele usará no máximo um único thread de CPU, a menos que você inicie sub -mais. Se sua máquina tiver pelo menos dois threads da CPU, você poderá maximizar os recursos da CPU usando scripts com vários threads em bash. A razão para isso é simples; Assim que um 'thread' secundário (leia -se: subshell) é iniciado, então esse thread subsequente pode (e frequentemente) usar um thread diferente da CPU.

Suponha por um momento que você tenha uma máquina moderna com 8 ou mais threads. Você pode começar a ver como se pudéssemos executar o código - oito encadeamentos paralelos ao mesmo tempo, cada um em um thread diferente da CPU (ou compartilhado em todos os threads) - dessa maneira ele executaria muito mais rápido que um único threadd Processo em execução em um único thread da CPU (que pode ser co-compartilhado com outros processos de execução)? Os ganhos obtidos dependerão um pouco do que está sendo executado, mas os ganhos haverão, quase sempre!

Excitado? Ótimo. Vamos mergulhar nele.

Primeiro, precisamos entender o que é uma subshell, como ele é iniciado, por que você usaria um e como ele pode ser usado para implementar o código Bash multithread.

Uma subshell é outro processo do cliente Bash executado/iniciado de dentro do atual. Vamos fazer algo fácil e iniciar um de dentro de um prompt de terminal Bash aberto:

$ Bash $ Sair Sair $ 

O que aconteceu aqui? Primeiro, começamos outra casca de bash (Bash) que começou e, por sua vez, produziu um prompt de comando ($). Então o segundo $ No exemplo acima é realmente uma casca de bash diferente, com um diferente PID (PID é o identificador do processo; um identificador de número exclusivo que identifica exclusivamente cada processo de execução em um sistema operacional). Finalmente saímos da subshell via saída e retornou ao subscel! De alguma forma, podemos prova de que é realmente o que aconteceu? Sim:

$ echo $ 220250 $ BASH $ echo $ 222629 $ saia saída $ echo $ 220250 $ 

Há uma variável especial em Bash $$, que contém o PID do shell atual em uso. Você pode ver como o identificador do processo mudou quando estávamos dentro de uma subshell?

Ótimo! Agora que sabemos o que são sub-explosões e um pouco sobre como eles funcionam, vamos mergulhar em alguns exemplos de codificação multithread e aprender mais!

Multi-threading simples em Bash

Vamos começar com um exemplo multi-thread simples simples, do qual a saída pode parecer um pouco confusa no início:

$ para i em $ (seq 1 2); eco $ i; feito 1 2 $ para i em $ (seq 1 2); Do eco $ i & feito [1] 223561 1 [2] 223562 $ 2 [1]- ECHO DOED $ I [2]+ ECHO DOED $ I $ $ 

Em primeiro para Loop (veja nosso artigo sobre Bash Loops para aprender a codificar loops
), simplesmente produzimos a variável $ i que variará de 1 a 2 (devido ao nosso uso do comando SEQ), que - curiosamente - é iniciado em uma sub -Shell!

OBSERVAÇÃO
Você pode usar o $ (…) sintaxe em qualquer lugar Dentro de uma linha de comando para iniciar uma subshell: é uma maneira muito poderosa e versátil de codificar sub -shells diretamente em outras linhas de comando!

No segundo para Loop, nós mudamos apenas um personagem. Ao invés de usar ; - Um idioma da sintaxe da Bash (final da linha) eol (final da linha) que encerra um determinado comando (você pode pensar sobre ele como entrar/executar/ir em frente), usamos &. Essa mudança simples contribui para um programa quase completamente diferente, e nosso código agora é multi-threaded! Ambos os Echo's processarão mais ou menos ao mesmo tempo, com um pequeno atraso no sistema operacional ainda precisando executar a segunda execução do loop (para ecoar '2').

Você pode pensar sobre & de maneira semelhante a ; com a diferença que & dirá ao sistema operacional para 'continuar executando o próximo comando, continue processando o código', enquanto ; vai esperar pelo comando de execução atual (rescindido por ;) para encerrar / terminar antes de retornar ao prompt de comando / antes de continuar a processar e executar o próximo código.

Vamos agora examinar a saída. Nós vemos:

[1] 223561 1 [2] 223562 $ 2 

A princípio, seguido de:

[1]- ECHO DOENCIDO $ I [2]+ ECHO $ ​​I $ $ 

E também há uma linha vazia no meio, que é o resultado de processos de fundo ainda em funcionamento enquanto aguardam a próxima entrada de comando (tente este comando algumas vezes na linha de comando, bem como algumas variações de luz, e você receberá um sinta como isso funciona).

A primeira saída ([1] 223561) nos mostra que um processo de fundo foi iniciado, com PID 223561 e o número do identificador 1 foi dado a isso. Então, já antes de o script chegar ao segundo eco (um eco provavelmente sendo uma declaração de código cara a ser executada), a saída 1 foi mostrado.

Nosso processo de fundo não terminou completamente, pois a próxima saída indica que iniciamos um segundo subshell/thread (conforme indicado por [2]) com PID 223562. Posteriormente, o segundo processo produz o 2 (“Indicativamente”: os mecanismos do sistema operacional podem afetar isso) antes do segundo tópico finalizar.

Finalmente, no segundo bloco de saída, vemos os dois processos terminando (conforme indicado por Feito), bem como o que eles estavam executando por último (como indicado por eco $ i). Observe que os mesmos números 1 e 2 são usados ​​para indicar os processos de fundo.

Mais multi-threading in Bash

Em seguida, vamos executar três comandos do sono, todos terminados por & (Então eles começam como processos de fundo) e vamos variar seus comprimentos de duração do sono, para que possamos ver com mais clareza como o processamento de fundo funciona.

$ Sono 10 e sono 1 e sono 5 e [1] 7129 [2] 7130 [3] 7131 $ [2]- DOMENO DE DONE 

A saída neste caso deve ser auto-explicativa. A linha de comando retorna imediatamente após o nosso Dormir 10 e dormir 1 e dormir 5 & comando e 3 processos de fundo, com seus respectivos PIDs são mostrados. Eu bati em entrar algumas vezes entre. Após 1 segundo, o primeiro comando concluído, produzindo o Feito para identificador de processo [2]. Posteriormente, o terceiro e o primeiro processo terminou, de acordo com suas respectivas durações do sono. Observe também que este exemplo mostra claramente que vários trabalhos estão em execução efetivamente, simultaneamente, em segundo plano.

Você também pode ter pegado o + Assine os exemplos de saída acima. Isso é tudo sobre controle de emprego. Veremos o controle de emprego no próximo exemplo, mas no momento é importante entender que + indica é o trabalho que será controlado se usarmos/executarmos comandos de controle de emprego. É sempre o trabalho que foi adicionado à lista de empregos em execução mais recentemente. Este é o trabalho padrão, que é sempre o mais recentemente adicionado à lista de trabalhos.

A - indica o trabalho que se tornaria o próximo padrão para os comandos de controle de emprego se o trabalho atual (o trabalho com o + sinal) terminaria. Controle de trabalho (ou em outras palavras; manuseio de threads de fundo) pode parecer um pouco assustador no começo, mas na verdade é muito útil e fácil de usar quando você se acostuma. Vamos mergulhar!

Controle de emprego em Bash

$ Sono 10 e sono 5 e [1] 7468 [2] 7469 $ Jobs [1]- Sono de corrida 10 e [2]+ Sono 5 e $ FG 2 Sono 5 $ FG 1 Sono 10 $ $ 

Aqui colocamos dois sono em segundo plano. Uma vez iniciados, examinamos os trabalhos atualmente em execução usando o empregos comando. Em seguida, o segundo fio foi colocado em primeiro plano usando o FG comando seguido pelo número do trabalho. Você pode pensar sobre isso assim; o & no sono 5 O comando foi transformado em um ;. Em outras palavras, um processo de fundo (não esperado) tornou -se um processo de primeiro plano.

Nós então esperamos pelo sono 5 comando para finalizar e subsequentemente colocou o sono 10 comando em primeiro plano. Observe que cada vez que fizemos isso, tivemos que esperar o processo de primeiro plano para terminar antes de recebermos nossa linha de comando de volta, o que não é o caso ao usar apenas processos de fundo (como eles estão literalmente 'em segundo plano').

Controle de emprego em Bash: Interrupção de empregos

$ sono 10 ^z [1]+ Sono parado 10 $ bg 1 [1]+ sono 10 e $ fg 1 sono 10 $ 

Aqui pressionamos Ctrl+Z para interromper um sono em corrida 10 (que para como indicado por Parou). Em seguida, colocamos o processo em segundo plano e finalmente o colocamos em primeiro plano e esperamos que ele termine.

Controle de emprego em Bash: Interrupção de empregos

$ sono 100 ^z [1]+ Sono parado 100 $ Kill %1 $ [1]+ Sono terminado 100 

Tendo iniciado um 100 segundos dormir, Em seguida, interrompermos o processo de execução por Ctrl+Z e depois matamos o primeiro processo de fundo iniciado/em execução usando o matar comando. Observe como usamos %1 neste caso, em vez de simplesmente 1. Isso ocorre porque agora estamos trabalhando com um utilitário que não está vinculado a processos de fundo, como FG e bg são. Assim, para indicar para matar que queremos efetuar o primeiro processo de fundo, usamos % seguido pelo número do processo em segundo plano.

Controle de trabalho em Bash: Processo decepcionado

$ sono 100 ^z [1]+ Sono parado 100 $ BG %1 [1]+ Sono 100 e $ DiELOOWN 

Neste exemplo final, encerramos novamente uma corrida dormir, e coloque -o em segundo plano. Finalmente executamos o Denem comando que você pode ler como: Desassociar todos os processos de fundo (trabalhos) do shell atual. Eles continuarão correndo, mas não são mais 'pertencentes' ao shell atual. Mesmo se você fechar seu shell e logout atuais, esses processos continuarão funcionando até que naturalmente terminem.

Esta é uma maneira muito poderosa de interromper um processo, coloque -o em segundo plano, deserdá -lo e depois fazer logout da máquina que você estava usando, desde que você não precisará mais interagir com o processo. Ideal para os processos de longa execução sobre o SSH que não podem ser interrompidos. Simplesmente Ctrl+Z o processo (que interrompe temporariamente), coloque -o em segundo plano, rejeite todos os empregos e logout! Vá para casa e tenha uma noite agradável e relaxada, sabendo que seu trabalho continuará correndo!

Exemplos de linha de comando de script e gerenciamento de processos com vários threades

Conclusão

Neste tutorial, vimos como implementar o Bash One-Liners com vários threads diretamente da linha de comando e exploramos por que a codificação com vários threads geralmente aumenta o desempenho de seus scripts. Também examinamos como os processos de fundo e primeiro plano funcionam e manipulamos filas de emprego. Finalmente, exploramos como rejeitar nossa fila de empregos do processo atual, fornecendo controle adicional sobre processos de execução. Aproveite suas novas habilidades encontradas e deixe um comentário abaixo com suas experiências de controle de emprego!

Tutoriais do Linux relacionados:

  • Uma introdução à automação, ferramentas e técnicas do Linux
  • Coisas para instalar no Ubuntu 20.04
  • Coisas para fazer depois de instalar o Ubuntu 20.04 fossa focal linux
  • Mastering Bash Script Loops
  • Gerenciamento de processos de fundo bash
  • Loops aninhados em scripts de basquete
  • Ubuntu 20.04 Guia
  • Coisas para fazer depois de instalar o Ubuntu 22.04 Jellyfish…
  • Exemplos úteis de linha de comando Bash e truques - Parte 6
  • Tutorial de depuração do GDB para iniciantes