47

Click here to load reader

Unix Process

Embed Size (px)

DESCRIPTION

Tech Talk realizado na Dito Internet sobre processos unix. O objetivo foi mostrar um pouco mais desse universo para o pessoal de TI.

Citation preview

Page 1: Unix Process

Unix Process

Page 2: Unix Process

Todos vocês já usaram...

Page 3: Unix Process

Tudo isso estásendo executado

através de um

PROCESSO

Page 4: Unix Process

Um pouco de história

- A programação unix existe desde 1970

- Foi inventado nos laboratórios Bell (Bell labs)

- Os conceitos e técnicas de programação unixnão são novidades. Essas técnicas vão além daslinguagens de programação.

- Essas técnicas não são modificadas há décadas

Page 5: Unix Process

Processos

- Quem sabe a diferença entre userland e kernel?

Page 6: Unix Process

Processos

Kernel- É a camada que está em cima do hardware. Ou seja, é o homem do meio entre toda interação que acontece entre a userland e o hardware

- Essas interações incluem coisas como:. Ler/Escrever no diretório de arquivos. Enviar arquivos pela rede. Alocar memória. Tocar música através dos auto-falantes

Devido ao seu poder, nenhum programa possui acesso direto ao Kernel

Page 7: Unix Process

Processos

Userland- É onde todos os seus programas são executados- Seu programa pode fazer muita coisa sem precisar do kernel:

. Realizar operações matemáticas

. Realizar operações com strings

. Controle de fluxo através de operações lógicas

Mas se você quiser fazer várias coisas legais terá que utilizar o kernel

Page 8: Unix Process

Processos

System call

- Qualquer comunicação entre o kernel e userland é feita através de system calls

- É a interface que conecta o kernel e a userland

- Define as interações que são permitidas entre o seu programa e o hardware

Page 9: Unix Process

Processos

Process identifier (pid)

- Todo processo possui um identificador único- Nada mais é que um número sequencial. É assim que o kernel vê o seu processo: como um número

>> puts Process.pid || $$ #system call: getpid

- Não está ligado a nenhum aspecto do conteúdo do processo.- Pode ser entendido por qualquer linguagem de programação

Page 10: Unix Process

Processos

Parents process (ppid)- Todo processo rodando no seu sistema possui um pai

- O processo pai é o processo que invocou outro determinado processo.

>> puts Process.ppid #system call: getppid

- O ppid pode ser importante quando estivermos detectando processos deamons

Page 11: Unix Process

Processos

File descriptors

- Representa arquivos abertos- Em unix tudo é arquivo!

. Isso significa que dispositivos são tratados como arquivo, sockets e pipes são tratados como arquivos e arquivos são tratados como arquivos!

- Qualquer momento que você abrir um recurso, é atribuido um número de file descriptor a esse recurso

Page 12: Unix Process

Processos

File descriptors- Não são compartilhados entre processos que não estão relacionados

- Eles vivem e morrem com o processo que eles estão ligados>> file = File.open(“path/to/the/file”)>> file.fileno=> 3

- É através do fileno que o kernel consegue manter o controle dos recursos que seu processo está utilizando

Page 13: Unix Process

Processos

File descriptors- Apenas recursos abertos possuem file descriptors- Todo processo unix vem com três recursos abertos

. STDIN

. STDOUT

. STDERR

- Existe uma limitação de 1024 file descriptors abertos por processo

Page 14: Unix Process

Processos

Environment variables

- São pares chave-valor que possuem dados para os processos

- Todo processo herda variáveis de ambiente de seus pais

- São definidas por processo e são globais para cada processo

$ MESS=‘teste’ ruby -e “puts ENV[‘MESS’]”

Page 15: Unix Process

Processos

Argumentos

- ARGV: argument vector

- É uma forma de passar argumentos para os processos

p ARGV$ ruby argv.rb foo bar -ba[“foo”, “bar”, “-ba”]

Page 16: Unix Process

Processos

Possuem nome

- Todo processo possue um nome e esse nome pode ser mudado durante seu runtime

>> puts $PROGRAM_NAME

- É uma forma eficiente de comunicar a tarefa que está sendo desenvolvida

=> irb

Page 17: Unix Process

Processos

Possuem um código de finalização

- Todo processo, ao finalizar, possui um código

- É um número entre 0-255 que denota se o processo finalizou com sucesso ou não

- A finalização com um código 0 indica que tudo ocorreu como esperado

- Mas... Os outros códigos são utilizados como forma de comunicação

Page 18: Unix Process

ProccessCAN use the

FORK

Page 19: Unix Process

Processos

Fork- É um dos conceitos mais poderosos da programação unix

- Permite que um processo em execução crie outro processo, utilizando recursos de programação para isso

- O novo processo criado é uma cópia exata do processo original

Page 20: Unix Process

Processos

Fork- O processo filho herda uma cópia de toda memória usada pelo processo pai bem como todos os file descriptors

Recapitulando...

- O ppid do processo filho é o pid do processo pai.- O processo filho possui o mesmo mapa de file descriptors que o processo pai

Page 21: Unix Process

Processos

Forkif fork

puts “entrando no if”else

puts “entrando no else”end

=> entrando no if=> entrando no else

WTF???- O método fork retorna duas vezes (ele cria outro processo, lembra??)- Retorna uma vez no processo pai e uma vez no processo filho

Page 22: Unix Process

Processos

Fork

puts “processo pai #{Process.pid}”if fork

puts “entrando no if atraves do processo #{Process.pid}”else

puts “entrando no else atraves do processo #{Process.pid}”end

=> processo pai 2000=> entrando no if atraves do processo 2000=> entrando no else atraves do processo 2010

- O processo filho é finalizado após executar o código que está no else- O retorno do fork no processo pai é o pid do filho. Já no processo filho o fork retorna nil

Page 23: Unix Process

Processos

Fork

Multicore Programming

- Não é garantido de ser distribuido através das CPUs disponíveis. Depende do SO

- É preciso ser feito com cuidado!

# system call => fork

Page 24: Unix Process

Processos

Processos orfãos

fork do5.times do

sleep 1puts “Eu sou orfão!”

endend

abort “Parent process died ...”

- O que acontece com um processo filho quando seu pai morre?

. Nada!

Page 25: Unix Process

Processos

CoW Friendly

- Copiar toda memória na hora do fork pode ser considerado um overhead

- Sistemas Unix modernos empregam uma técnica chamada Copy on Write para evitar o overhead

- A cópia da memória é evitada até que alguma escrita seja necessária

- Dessa forma o processo pai e o processo filho compartilham a memória até uma escrita ser realizada pelo processo filho

Page 26: Unix Process

Processos

CoW Friendlyarr = [1,2,4]

fork do# nesse momento não há copia de memória# a leitura é feita de forma compartilhadaputs arr

end

fork do# Ao modificar o array uma cópia do array precisa ser feita# para o processo filhoarr << 4

end

- Isso mostra que realizar um fork é rápido

- Os processos filhos possuem uma cópia dos dados modificados. O resto pode ser compartilhado

Page 27: Unix Process

Processos

CoW Friendly

- MRI não é CoW friendly. O garbage collector utiliza um algoritmo ‘mark-and-sweep’ que não é compatível com cow

. O algoritmo realiza uma iteração por todo objeto existente marcando se o mesmo deve ser coletado ou não

. Dessa forma, quando o garbage collector rodar toda memória sera copiada para o processo filho

Page 28: Unix Process

Processos

Podem esperar- Realizar um fork e não esperar o resultado é interessante para tarefas assincronas

message = “Opa, bão?”recipient = “[email protected]

fork doStatsCollector.record message, recipient

end

#continua o envio da mensagem

- Mas em alguns outros casos você quer manter o controle sobre seus processos filhos

Page 29: Unix Process

Processos

Podem esperar

fork do5.times do

sleep 1puts “Eu sou orfão!”

endend

- Basta utilizar em ruby: Process.wait

Process.waitabort “Processo pai morreu ...”

=> “Eu sou orfão!”=> “Eu sou orfão!”=> “Eu sou orfão!”=> “Eu sou orfão!”=> “Eu sou orfão!”=> “Processo pai morreu ...”

Page 30: Unix Process

Podem esperar

- Process.wait

Processos

. É uma chamada bloqueante que faz o processo pai esperar por um de seus filhos terminar a execução

. É você que precisa saber qual processo está sendo terminado. Process.wait retorna o pid do processo filho

Page 31: Unix Process

Processos

Podem esperar

- Condições de corrida. O que acontece quando um processo pai demora para realizar a chamada ao metodo wait?

. O Kernel coloca todas as informações de exit dos processos filhos em uma fila!

. Se Process.wait for chamado e não existir processo filho será lançada uma exception

Page 32: Unix Process

Processos

Zombieee

- É sempre bom limpar os processos filhos

- O Kernel guarda informações de todos os processos filhos em um fila, estão lembrados?

- Se nós não retirarmos ela de lá, quem irá?NINGUEM

- Estamos gastando mal os recursos do Kernel

Page 33: Unix Process

Processos

Zombieee

message = “Opa, bão?”recipient = “[email protected]

pid = fork doStatsCollector.record message, recipient

end

Process.detach(pid)#continua o envio da mensagem

- Arrumando nosso exemplo

- Basicamente, Process.detach dispara uma nova thread que terá como terefa esperar o processo filho terminar

Page 34: Unix Process

Processos

Zombieee- Todo processo filho que termina e não possui seus status coletado é considerado zombie

pid = fork { sleep(1) }puts pidsleep

$ ps -ho pid,state -p [pid do processo]

- O status impresso será z ou Z+

Page 35: Unix Process

Processos

Recebem sinais

- Process.wait é uma chamada bloqueante- Como esperar por processos filhos em processos pais que estão sempre ocupados?

. Basta trabalhar com sinais!

. CHLD é o sinal que o kernel envia para o processo pai indicando que um processo filho foi finalizado

Page 36: Unix Process

Processos

Recebem sinais

child_process = 3dead_process = 0child_process.times do

fork dosleep 3

endend

trap(:CHLD) dowhile pid = Process.wait(-1, Process::WNOHANG)

puts piddead_process += 1exit if dead_process == child_process

endend

loop do (Math.sqrt(rand(44)) ** 8).floorsleep 1

end

Page 37: Unix Process

Processos

Recebem sinais

- É uma forma de comunicação assincrona

- Quando um processo recebe um sinal do Kernel as seguintes ações podem ser tomadas:

. Ignorar

. Realizar algum comportamento específico

. Realizar o comportamento padrão

Page 38: Unix Process

Processos

Recebem sinais

- Os sinais são enviados através do Kernel

- Basicamente, o Kernel é o middleman utilizado pelos processos para enviarem sinais uns aos outros

Page 39: Unix Process

ComputadorLIGADO rodando

task remotaNUNCA MAIS

Page 40: Unix Process

Processos

Recebem sinais

- Se sua tarefa já estiver rodando em um console basta enviar o sinal de stop para que a tarefa seja interrompida

- Após sua interrupção basta colocá-la para rodar em background através do comando bg

- Basta remover o vínculo com o terminal através do comando disown

Page 41: Unix Process

Processos

Podem se comunicar

- Existem algumas formas de realizar IPC (Inter-process communication)

. Pipe

. Sockets

Page 42: Unix Process

Processos

Podem se comunicar- Pipe

. É um caminho de mão única de fluxo de dados

reader, writer = IO.pipe => [#<IO:fd 5>, #<IO:fd 6>]writer.write(“Galo doido não perde em casa”)writer.close

puts reader.read

=> “Galo doido não perde em casa”

. É um stream de dados!

Page 43: Unix Process

Processos

Podem se comunicar- Pipe

. É um recurso compartilhado como qualquer outro

reader, writer = IO.pipe => [#<IO:fd 5>, #<IO:fd 6>]

fork doreader.close10.times do

#trabalhando...writer.puts “Quase acabando”

endend

writer.closewhile message = reader.gets

$stdout.puts messageend

Page 44: Unix Process

Processos

Podem se comunicar- Sockets. Pode ser um socket unix, para comunicaçãolocal. Pode ser um socket tcp, para comunicaçãoremota

- Outra possível solução seria RPC

Page 45: Unix Process

Processos

Deamon- São processos que rodam em background e que não estão ligados a nenhum terminal controlado pelo usuário

- Tem um processo deamon que é muito importante para o sistema operacional

. É o pai de todos. É o processo chamado init, seu ppid é 0 e o seu pid é 1

Page 46: Unix Process

Processos

Deamon

- Process group e session group

$ git log | grep shipped | less

- Todo sinal enviado para o pai de um process group é encaminhado para os filhos

- Todo sinal encaminhado para um session group é encaminhado para os processos que fazem parte desse grupo