O que determina se um executável pode ser executado em diferentes processos independentes simultaneamente?

0

Eu publiquei uma pergunta sobre como executar um executável (um visualizador de PDF) sob o vinho independentemente em vários processos (independente significa que não há comunicação entre eles, não é computação paralela). Ouvi dizer que o editor de PDF (uma edição aprimorada do visualizador) da empresa não pode fazer isso.

Perguntas

  • Então, eu me pergunto o que torna um arquivo executável capaz ou não ser capaz de executar independentemente em vários processos?
  • É implementado pelo próprio programa, por algumas bibliotecas?
  • O sistema operacional não pode fazer isso acontecer?
por Tim 10.10.2014 / 17:20

2 respostas

2

Isso é quase certamente implementado pelo próprio programa, e provavelmente impossível para o sistema operacional forçar todos os programas, exceto os mais rudimentares.

Se, no entanto, você souber a maneira pela qual o programa decide que já está sendo executado, e essa maneira é algo que você pode influenciar, você pode realmente obter um executável para iniciar um novo processo (ou não).

Algumas aplicações tornam isso particularmente fácil, como o Emacs. A maneira padrão de executar o Emacs é iniciar um novo processo para cada chamada. Mas você também pode executar explicitamente o Emacs no modo de servidor e, em seguida, executar emacsclient explicitamente para informar ao servidor existente para visitar um novo arquivo.

Como exemplo oposto, o Firefox oferece uma opção de linha de comando -no-remote que força um novo processo a ser iniciado, enquanto o padrão é interagir com um processo já em execução, se possível.

Muitos aplicativos simples e caseiros verificam se outra versão de si mesmo já está em execução, simplesmente consultando ps . Isso pode ser contornado de várias maneiras. O problema com o software de força industrial é que o usuário quase nunca sabe como determinado aplicativo decide se já está em uso ou não. Mesmo no Unix, onde você pode inspecionar todos os arquivos abertos com os quais um executável está interagindo, não há garantia de que você pode descobrir qual deles (se algum deles) é responsável por registrar o fato de que o aplicativo está sendo executado.

    
por 10.10.2014 / 18:46
1

Um processo é uma instância de um programa. Um programa pode ser instanciado várias vezes, isto é, vários processos podem ser criados com o mesmo código executável carregado. Eu gostaria de citar uma linha de Entendendo o Kernel do Linux por Daniel P. Bovet e Marco Cesati:

It is important to distinguish programs from processes; several processes can execute the same program concurrently, while the same process can execute several programs sequentially.

Basicamente, isso significa que, enquanto um programa pode ser executado em várias instâncias, uma única instância só pode carregar um código executável de cada vez. Assim, a partir daí, poderíamos dizer que nothing impede que um programa seja executado em várias instâncias, porque não há absolutamente nenhuma razão para proibi-lo. Naturalmente, esses processos não compartilharão nada além do código de execução. Páginas de memória, descritores de arquivos (que podem dizer respeito a arquivos idênticos) e assim por diante ... são completamente independentes de um processo para outro.

Outro ponto parece importante para mim quando se trata de sistemas do tipo Unix (mesmo livro):

Unix-like operating systems adopt a process/kernel model. Each process has the illusion that it’s the only process on the machine, and it has exclusive access to the operating system services.

Na verdade, é por isso que os sistemas Unix são multiprocessamento / multiprogramação, ou pelo menos, é a política sobre a qual esse recurso é baseado. Assim, devido a esse fato, não há como um processo saber de forma nativa que outro processo, executando exatamente o mesmo código, está aguardando ou trabalhando em outra CPU.

No entanto, cada processo sabe uma coisa: o sistema está sendo executado pelo kernel, e os serviços do kernel estão à disposição do processo o tempo todo que ele vai gastar trabalhando em uma CPU. Graças a isso, é possível que um processo consulte o kernel sobre outros processos em execução como instâncias do mesmo executável. A primeira solução que me vem à mente é ler o sistema de arquivos /proc virtual. Este FS age como uma interface entre o usuário / aplicativo e o kernel (já que esses arquivos representam estruturas e dados do kernel). Neste sistema de arquivos, cada processo recebe um diretório (nomeado com seu PID) e, dentro desse diretório, você encontrará um link chamado exe . Por exemplo, aqui está o meu diretório bash process ', PID 22343:

lrwxrwxrwx /proc/22343/exe -> /bin/bash*

Agora, navegando pelo sistema de arquivos, você poderá encontrar processos que executam o mesmo código executável, ou seja, processos para os quais o link exe tem como alvo o mesmo arquivo executável.

No entanto, como todos os sistemas Unix não implementam /proc da mesma maneira, os desenvolvedores pretendem usar uma solução mais portátil, que depende de algo que praticamente todos os sistemas Unix entendem: arquivos comuns. É para isso que .pid arquivos estão aqui.

Na maioria das vezes, você encontrará esses arquivos em /run . Por exemplo:

-rw-r--r-- /run/acpid.pid
-rw-r--r-- /run/atd.pid
-rw-r--r-- /run/crond.pid

Esses arquivos são criados pelo aplicativo ao qual pertencem e usados como marcadores de se uma instância de um programa está sendo executada ou não. Normalmente, o conteúdo deste arquivo é feito simplesmente do PID do processo em execução. Nesse caso, tenho um processo acpid em execução, com PID 1503, e é exatamente isso que está no arquivo PID.

Agora, como todos os processos do mesmo programa compartilham o mesmo código de execução, eles compartilham suas constantes (pelo menos, seus valores). Por esse motivo, se cada instância souber onde procurar pelo arquivo PID, programar um programa de instância única é muito fácil:

if (the pid file exists) then
    send a signal to the running process or just bring it on the foreground
    exit since the work is going to be handled by the already-running process
else
    actually start the program, the first instance
endif

O uso de sinais no primeiro caso é o comportamento que eu mais tenho visto, no entanto, se seu aplicativo usa um IPC mais sofisticado (soquetes, filas de mensagens, ...), você pode usá-lo para informar que o usuário pediu algo que precisa fazer.

    
por 10.10.2014 / 21:43

Tags