Gerenciar um processo com PID dinâmico

Iniciado por IgorRafael, 24 de Julho de 2012, 10:32

tópico anterior - próximo tópico

IgorRafael

Olá,
meu problema é o seguinte, estou comparando o custo de sockets implementados em diversas linguagens, mas quando o executo em algumas linguagens ele não permanece com um PID estático, pelo contrário fica mudando dinamicamente, aí não consigo utilizar o comando pmap (lista as bibliotecas utilizadas pelo programa e seu custo(uso de memória)) <PID>, alguém sabe como faço para    gerenciar nesse caso?
Ps. Já tentei com o PPID, mas surgem bibliotecas que não são do uso direto do processo do socket, e isso prejudica minhas comparações.
Grato!

irtigor

Provavelmente fazem fork, talvez um cgroup ajude ou o uso do valgrind seja mais adequado (algo que marque/separe o processo pai e filhos).

IgorRafael

Ótimo, vou tentar seguir suas dicas e reporto algo aqui.
Obrigado!

zekkerj

Igor, o número do processo é estático, não dinâmico. Ele acompanha o processo por toda sua vida. Se o PID do processo muda, isso significa que o processo está morrendo e sendo recriado por outro.

Isso é esperado para processos associados com o "upstart", que é o superdaemon que controla a inicialização do Ubuntu.
[O Upstart substitui o antigo superdaemon "init"]

Exemplos de processos associados com o upstart são os controladores de terminais virtuais --- getty, atty, etc.

Outro processo com a mesma característica --- morre e reaparece --- é o "modem-manager". Quando ele morre, o NetworkManager cria um novo processo. Com o detalhe que de o processo criado, por sua vez, cria um processo filho e morre. Isso faz com que o processo "modem-manager" resultante tenha PPID igual a 1.
[Quando o pai de um processo em execução morre, o processo filho é "adotado" pelo Upstart/Init, ou seja, o PPID dele passa a ser "1".]

Dito isto, é importante ter em mente que o que identifica um processo é o seu número (PID), não o nome da imagem que está sendo executada. É possível inclusive que um PID mude de imagem, durante a sua execução (ou seja, você estava executando um processo "bash" e de repente ele se torna um "vi" ou um "login". Mas o PID permanece o mesmo, basta que o processo original execute a syscall "exec".

Se você tem um programa que está morrendo e nascendo repetidamente num intervalo muito curto, você tem um problema. Criar e destruir processos é uma tarefa dispendiosa para o sistema. Por exemplo, quando o Upstart/Init detecta que um processo filho está morrendo várias vezes seguidas, ele bloqueia o renascimento do processo ("respawn"), pois isso é indício de que o processo tem algum problema de configuração (erro de sintaxe, biblioteca faltando, etc).
Pesquise antes de perguntar, sua dúvida pode já ter sido respondida.
Não respondo dúvidas por MP, coloque sua dúvida no fórum onde ela pode ser pesquisada pelos seus colegas!
Não venha ao fórum apenas para perguntar. Se você sabe a resposta de um problema, porque não ajudar seu colega? ;D

zekkerj

Como eu disse, criar um processo é uma tarefa dispendiosa. O sistema tem que alocar uma área de código para a imagem, depois uma área de dados, e por fim uma área de stack pra dados dinâmicos. Também tem que colocar esse processo na fila de escalonamento, definir sua prioridade, ver como vai ficar a área de swap do processo. Se o processo usar bibliotecas dinâmicas, o sistema tem que ver se essas bibliotecas já estão carregadas; se estiverem, é preciso mapear a área de memória virtual delas pra seu processo. Do contrário, elas têm que ser carregadas do disco. E, claro, a imagem, em si, tem que ser carregado do disco, também.

O escalonamento de processos também é dispendioso. Quando um processo é escalonado, o sistema tem que restaurar todas as áreas de memória dele, mais todo o ambiente de execução do processo, conforme estava no momento em que o processo foi desescalonado. O que significa que o desescalonamento também é dispendioso: todas essas informações têm que ser salvas.

Se você tem um algoritmo que precisa ser dividido em vários processos que nascem e morrem rápido, considere usar "threads", que são "processos leves" [lightweight processes]. Threads compartilham a área de código e dados com o processo principal; dependendo do tipo de thread, pode compartilhar também a área de swap ou não. As threads podem ser de kernel, ou nativas, ou de usuário, ou green.

Como as threads compartilham as áreas de código e dados na memória, é mais rápido pra criar uma thread. Também é mais rápido pra escalonar uma thread, supondo que o processo anterior era outra thread do mesmo processo.

O senão de usar threads é que como todas compartilham a mesma área de dados, trabalhar com variáveis globais e/ou estáticas é delicado. Todas as threads têm acesso a essas variáveis. Uma thread pode tentar usar esses valores, enquanto a outra o está alterando. Isso cria uma condição chamada "região crítica" que precisa ser tratada, no código.
Pesquise antes de perguntar, sua dúvida pode já ter sido respondida.
Não respondo dúvidas por MP, coloque sua dúvida no fórum onde ela pode ser pesquisada pelos seus colegas!
Não venha ao fórum apenas para perguntar. Se você sabe a resposta de um problema, porque não ajudar seu colega? ;D

IgorRafael

Compreendi bem o que você passou. Não existe PID dinâmicono caso o processo está sendo eliminado e outro é gerado. Mas não compreendo o que fica matando o processo, acredito não ter falha no código, mas vou me ater aos detalhes. Obrigado! E ótima explicação!

zekkerj

Falei, falei, falei, e não perguntei o essencial: que processo é esse que vc está acompanhando, e com qual objetivo?
Pesquise antes de perguntar, sua dúvida pode já ter sido respondida.
Não respondo dúvidas por MP, coloque sua dúvida no fórum onde ela pode ser pesquisada pelos seus colegas!
Não venha ao fórum apenas para perguntar. Se você sabe a resposta de um problema, porque não ajudar seu colega? ;D

IgorRafael

Um exemplo em Phyton;
Eu executo o socket server com o seguinte código:
#!/user/bin/python

import socket

host = ''
port = 7000
addr = (host, port)
serv_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serv_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
serv_socket.bind(addr)
serv_socket.listen(10)

print 'aguardando conexao'
con, cliente = serv_socket.accept()
print 'conectado'
print "aguardando mensagem"
recebe = con.recv(1024)

print "mensagem recebida: "+ recebe
serv_socket.close()

Pronto !

Compilo com phyton socketServer.py

Filtro com
$ps aux| grep socketServer.py

Pego o PID e tento:

$ pmap PID

Não sai nada.

Filtro novamente e vejo que existe outro PID, no caso outro processo. Mas o que está matando e iniciando um novo processo?!

Grato!


Tucotuco

Igor,

Ja me aconteceu antes, a kernell matar o processo porque ele consumia muita memoria. Se nao estou em erro existem poucas situacoes em que a Kernell pode matar um processo, mas se este estiver a consumir demasiados recursos do sistema entao essa fail-safe eh activada.

Se realmente isto estiver a acontecer podes encontrar evidencias nos logs de sistema,
less /var/log/kern.log

procura pelo nome do teu processo ou entao pela hora a que o executaste.
"Maria Lisboa, cidade mulher da minha vida"

IgorRafael

Dei uma olhada e nada a respeito no log do kernel.
E também , no máximo consome 16 megas quando em execução, não acho isso uma sobrecarga para o kernel.

zekkerj

Veja só, vc tem chamadas de I/O em seu código, mas não vi nenhum tratamento pros possíveis erros de I/O...
Pesquise antes de perguntar, sua dúvida pode já ter sido respondida.
Não respondo dúvidas por MP, coloque sua dúvida no fórum onde ela pode ser pesquisada pelos seus colegas!
Não venha ao fórum apenas para perguntar. Se você sabe a resposta de um problema, porque não ajudar seu colega? ;D

IgorRafael

Pode ser que quando ele tente a conexão e o client não esteja rodando ele encerre o processo e crie outro?

zekkerj

Pesquise antes de perguntar, sua dúvida pode já ter sido respondida.
Não respondo dúvidas por MP, coloque sua dúvida no fórum onde ela pode ser pesquisada pelos seus colegas!
Não venha ao fórum apenas para perguntar. Se você sabe a resposta de um problema, porque não ajudar seu colega? ;D


zekkerj

Essa mudança de PID ocorre continuamente, ou apenas uma vez?
Pesquise antes de perguntar, sua dúvida pode já ter sido respondida.
Não respondo dúvidas por MP, coloque sua dúvida no fórum onde ela pode ser pesquisada pelos seus colegas!
Não venha ao fórum apenas para perguntar. Se você sabe a resposta de um problema, porque não ajudar seu colega? ;D