Em Java, cria-se um processo com a classe ProcessBuilder, usando o nome do processo como parâmetro de entrada (nomeProcesso como String).
O processo é iniciado com o método start() da classe ProcessBuilder.
ProcessBuilder pb = new ProcessBuilder(nomeProcesso);
Process p = pb.start();
Um exemplo completo de uma classe Java chamada "lancarEEsperarProcessoWin32" para lançar processos está descrito na figura 3.1.1.1.
public class lancarEsperarProcessoWin32 {
ProcessBuilder pb; // Instância de ProcessBuilder para construir e iniciar processos
Process p; // Instância de Process para representar o processo em execução
// Método para lançar um processo Win32 com base no nome do executável (String s)
public void lancarProcessoWin32(String s) {
pb = new ProcessBuilder(s); // Cria um ProcessBuilder com o nome do processo
try {
p = pb.start(); // Inicia o processo
System.out.println("Processo executando."); // Exibe mensagem de sucesso
} catch (IOException e) {
p = null; // Em caso de erro, define 'p' como nulo (sem processo em execução)
}
}
// Método para esperar o término do processo lançado
public void esperarFimProcessoWin32() {
if (p != null) { // Verifica se há um processo em execução
try {
p.waitFor(); // Aguarda até que o processo termine
System.out.println("Processo terminou."); // Exibe mensagem de término
} catch (InterruptedException e) {
p = null; // Em caso de interrupção, define 'p' como nulo
}
}
}
// Método principal (entry point) para testar a classe
public static void main(String[] args) {
lancarEsperarProcessoWin32 lep = new lancarEsperarProcessoWin32(); // Cria uma instância da classe
lep.lancarProcessoWin32("c:\\Windows\\system32\\mspaint.exe"); // Lança o processo do MS Paint
lep.esperarFimProcessoWin32(); // Espera o término do processo do MS Paint
}
}
lancarEsperarProcessoWin32.pb para ProcessBuilder e p para Process.lancarProcessoWin32 é um método que lança um processo com base no nome do executável fornecido como argumento. Ele cria um novo ProcessBuilder, inicia o processo e exibe uma mensagem se a operação for bem-sucedida.esperarFimProcessoWin32 é um método que espera que o processo em execução termine e exibe uma mensagem quando isso ocorre.main é o ponto de entrada do programa e é usado para testar a classe. Ele cria uma instância de lancarEsperarProcessoWin32, lança o processo do MS Paint e espera que ele termine.main() que serve como ponto de entrada.public class lancarEEsperarProcessoJAVA {
public static void main(String[] args) {
// Forma de executar a partir de Java um processo Java
Process p = null; // Declaração de uma variável de processo
try {
// Executa um processo Java a partir do comando "java -jar" com o arquivo T1.jar
p = Runtime.getRuntime().exec("java -jar C:\\Users\\jpais\\Desktop\\T1.jar");
System.out.println("T1 executando."); // Exibe que o processo T1 está em execução
} catch (IOException e) {
e.printStackTrace(); // Em caso de erro, imprime a exceção
}
if (p != null) { // Verifica se o processo foi lançado com sucesso
try {
// Espera pelo término do processo T1
p.waitFor();
System.out.println("T1 terminou."); // Exibe que o processo T1 terminou
} catch (InterruptedException e) {
System.err.println(e.getMessage()); // Em caso de interrupção, imprime a mensagem de erro
}
}
}
}
p do tipo Process para representar o processo a ser lançado.try, é utilizado Runtime.getRuntime().exec() para executar um processo Java com o comando "java -jar" e o arquivo T1.jar.IOException), é impresso o rastreamento da exceção.try, p.waitFor() é usado para aguardar o término do processo T1.InterruptedException), a mensagem de erro é impressa.Em Java, a comunicação entre processos independentes (IPC - Inter-Process Communication) na mesma máquina pode ser realizada com as seguintes tecnologias:
- Memória partilhada.
- Sockets via TCP (Transfer Control Protocol).
- Sockets via UDP (User Datagram Protocol).
Para a comunicação entre máquinas diferentes, as tecnologias utilizadas incluem:
- Sockets via TCP (Transfer Control Protocol).
- Sockets via UDP (User Datagram Protocol).
O tempo necessário para a passagem de informações entre processos pode variar, e os tempos aproximados para cada técnica são:
- Memória partilhada com 1 núcleo de CPU: 1,5 microssegundos.
- Memória partilhada com mais de 1 núcleo de CPU: 0,7 microssegundos.
- TCP com 1 núcleo de CPU: 30 microssegundos.
- TCP com mais de 1 núcleo de CPU: 22 microssegundos.
- UDP com 1 núcleo de CPU: 5 microssegundos.
- UDP com mais de 1 núcleo de CPU: 8 microssegundos.
Essas tecnologias permitem que os processos em Java se comuniquem de maneira eficiente, escolhendo a melhor opção com base nas necessidades específicas de desempenho e requisitos de comunicação.
Em Java, a comunicação entre processos independentes (IPC - Inter-Process Communication) na mesma máquina pode ser eficientemente realizada por meio de memória partilhada, conhecida como memória mapeada.
A memória mapeada em Java é um modelo que mapeia o conteúdo de um arquivo em uma área de memória virtual. Isso permite manipular a memória como um buffer normal, sem a necessidade de operações de leitura e escrita explícitas no arquivo. A disponibilidade do conteúdo na memória principal do processo pode variar, afetando o tempo de acesso aos dados.
MappedByteBuffer, que representa um buffer de acesso direto com conteúdo semelhante ao de um arquivo.public abstract class MappedByteBuffer extends ByteBufferMappedByteBuffer são criadas com o método FileChannel.map e existem até serem eliminadas no processo.MappedByteBuffer.MappedByteBuffer for truncado ou fechado por um processo, todos os processos não poderão mais acessá-lo, gerando uma exceção de acesso.MappedByteBuffer force() – obriga a atualização da memória secundária com o conteúdo do buffer.boolean isLoaded() – indica se o conteúdo do buffer está em memória principal.MappedByteBuffer load() – carrega o conteúdo do buffer em memória principal.A memória partilhada em JAVA é uma memória mapeada de um ficheiro que tem de ser conhecido dos vários processos através do path e nome do ficheiro. A classe para implementar a comunicação entre processos tem o nome “canalComunicacao”
public class canalComunicacao {
// Ficheiro
private File ficheiro;
// Canal que liga o conteúdo do ficheiro ao Buffer
private FileChannel canal;
// Buffer
private MappedByteBuffer buffer;
// Dimensão máxima em bytes do buffer
final int BUFFER_MAX = 30;
// Construtor vazio
public canalComunicacao() {
ficheiro = null;
canal = null;
buffer = null;
}
// Abre o canal de comunicação
public boolean abrirCanal() {
// Cria um ficheiro com o nome "comunicacao.dat"
ficheiro = new File("comunicacao.dat");
// Cria um canal de comunicação de leitura e escrita
try {
canal = new RandomAccessFile(ficheiro, "rw").getChannel();
} catch (FileNotFoundException e) {
return false;
}
// Mapeia para memória o conteúdo do ficheiro
try {
buffer = canal.map(FileChannel.MapMode.READ_WRITE, 0, BUFFER_MAX);
} catch (IOException e) {
return false;
}
return true;
}
// Recebe uma mensagem convertendo-a numa String
String receberMensagem() {
String msg = new String();
char c;
buffer.position(0);
while ((c = buffer.getChar()) != '\0')
msg += c;
return msg;
}
// Envia uma String como mensagem
void enviarMensagem(String msg) {
char c;
buffer.position(0);
for (int i = 0; i < msg.length(); ++i) {
c = msg.charAt(i);
buffer.putChar(c);
}
buffer.putChar('\0');
}
// Fecha o canal entre o buffer e o ficheiro
void fecharCanal() {
if (canal != null)
try {
canal.close();
} catch (IOException e) {
canal = null;
}
}
}