This is an old revision of the document!


Programa a ser paralelizado

Deve ter 3 métodos: inicia(); finaliza(); executa(parametros)

O programa deve ter um main que recebe parâmetros (strings). O primeiro parametro será sempre a string rmi usada para conexão com o gerente (Naming.rebind(string)) e o segundo um dos métodos citados acima.

O método “executa” é o único que recebe parametros e pode ser utilizado para qualquer coisa de acordo com seus parametros. Pode ser usado até mesmo para chamar outros métodos a partir dele.

Qualquer um dos métodos acima, após concluir sua computação, deve fazer uma conexão rmi retornando os resultados de suas computações para o gerente. Apenas uma conexão rmi deve ser realizada por cada computação e após ela ser feita o programa deve ser finalizado.

inicia()

Realiza rotinas iniciais do programa e cria as tarefas na forma de strings que serão posteriormente passadas para o executa

Retorno do rmi: deve retornar uma lista de strings onde cada string é uma tarefa a ser computada usando a seguinte estrutura: Boolean status = h.listaTarefas(string []listaTarefas);

este método rmi (“listaTarefas”) pode ser chamado a qualquer momento adicionando novas tarefas.

finaliza()

Conclui o programa juntando todos os resultados das computações Retorno do rmi: informa a conclusão do programa chamando o seguinte método rmi: Boolean status = h.finaliza(true);

executa(parametros)

Executa uma determinada tarefa, os parâmetros são passados via linha de comando como string. O primeiro parametro passado é a id da tarefa e deve ser usada no retoro na resposta rmi e no nome dos arquivos com resultados parciais das computações, se necessário. Os demais podem ser usados livremente. Como os parãmetros são sempre string, pois são passagens de argumento, devem ser convertidos para os tipos de dados desejados.

Retorno do rmi: deve retornar o id da tarefa e o seu status ou redistribui em novas tarefas. Se a tarefa foi concluída com exito o parâmetro é true se não o parâmetro é false

Boolean status = h.tarefa(int, tarefa, boolean status);

Boolean status = h.listaTarefas([]listaTarefas);

no caso de redistribuíção de tarefas será subentendido que a tarefa foi concluída com exito e foi quebrada em outras subtarefas

	

O que pode ser uma tarefa:

Um exemplo de tarefa seria uma figura ao qual deve ser aplicado um algorítmo. Portanto o método “inicia” pode particionar uma determinada imagem em várias subimagens para poder computar cada uma em um nodo diferente. Desta maneira o nome de cada subimagem pode ser a tarefa, logo quando o “gerente” distribuir as tarefas ele vai passar o seu nome para o método executa. depois de todas as tarefas terem sido executadas, o método “finaliza” é chamado para computar os resultados parciais que devem obrigatóriamente estarem armazenados em arquivos.

O programa gerente:

Controla a distribuíção das tarefas nos nodos.

Tem uma lista com os nodos a serão utilizados, que é passada como parâmetro de entrada. Sendo o primeiro da lista o nodo onde o gerente está rodando.

cria uma lista de nodos

Tem um vector em que cada elemento é outro vector:

No vector principal, cada indice corresponde a uma tarefa a ser executada

No vector interno (cada indice do vector principal), tem tres elementos:

elemento 1: tipo String - corresponde a tarefa. Será passada para o executa quando a tarefa for distribuída

elemento 2: tipo byte - corresponde ao status da tarefa.

Valor 0: aguardando

Valor 1: processando

Valor 2: finalizada

elemento 3: id do nodo que esta processando a tarefa

elemento 4: tipo tempo - tempo de inicio da tarefa

elemento 5: tipo tempo - tempo gasto na realização da tarefa

O identificador da tarefa é o próprio indice do vector principal.

Este vector é prenchido em tempo de execução quando for chamado o metodo “inicia” do programa a ser paralelizado.

De tempos em tempos este vector com as tarefas deve ser gravado em arquivo para que se possa monitorar o status do processamento

Algorítmo:

início start do servidor rmi chamada do método “inicia” (pode ser no nodo local ou em outro) aguarda a conexao rmi para informar a lista de tarefas monta a lista de tarefas

inicio do escalonador para distribuir as tarefas verifica se tem nodo livre se tem, varre lista de tarefas a procura de uma tarefa a ser distribuída se encontra tarefa, encaminha para o nodo disponível (chama vis rsh um script rum_cliente que deve chamar do metodo “executa” do programa a ser paralelizado.), muda o status do nodo para processando e atribui o id do nodo a tarefa

quando todas as tarefas forem finalizadas, chama o metodo “finaliza” do programa a ser paralelizado.

Modelo de implementação do Programa a ser paralelizado.

Cada método será chamado pelo programa gerente separadamente, portanto não compartilham variáveis eles tem que ser visualizados como programas diferentes rodando em momentos diferentes, portanto dados devem ser trocados através de arquivos. cada método pode ser desdobrado em outros conforme a necessidade do algoritmo, mas apenas estes serão chamados diretamente pelo programa “gerente”

 
import java.rmi.*;
import java.util.*;
import java.io.*;
 
class Cliente
{
	public static void main(String [] args)
	{
		if (args.length <= 2)
		{
			System.out.println("Numero insuficiente de parametros:" + args.length);
			System.exit(0);
		}
 
		if (args[1].equals("inicia"))
			inicia(args[0]);
		if (args[1].equals("finaliza"))
			finaliza(args[0]);
		if (args[1].equals("executa"))
			executa(args);
	}
 
	public static void inicia(String str)
	{
	//rotina de inicio
	//particiona uma imagem em 4 partes
		//grava cada parte em um arquivo no diretorio figs/
	//passa as tarefas via rmi para o programa gerente como sendo o proprio nome das figuras que foram particionadas e na qual serão aplicados o algoritmo:
 
		try
		{
//--------------------------------------------------------------------------------------------------------
//cria lista de tarefas
 
			String []lista = { "figs/fig0.jpg" , "figs/fig1.jpg" , "figs/fig2.jpg" , "figs/fig3.jpg" };
 
 
 
 
 
 
//--------------------------------------------------------------------------------------------------------
 
			//envia lista de tarefas por rmi
			InterfaceGerente h = (InterfaceGerente) Naming.lookup(str);
			Boolean status = h.listaTarefas(lista);
 
			System.out.println("rotina de inicio");
		}
		catch (Exception e)
		{
			System.out.println ("Erro: " + e);
		}
	}
 
	public static void finaliza(String str)
	{
	//agrupa as imagens ou arquivos que foram gerados nos resultados parciais
	//retorna status de fim do programa
//--------------------------------------------------------------------------------------------------------
//finaliza computacao juntando resultados parciais
 
 
 
 
 
 
 
//--------------------------------------------------------------------------------------------------------
 
		System.out.println("final do programa");
		try
		{
			InterfaceGerente h = (InterfaceGerente) Naming.lookup(str);
			Boolean status = h.finaliza(true);
		}
		catch (Exception e)
		{System.out.println ("Erro: " + e);}
	}
 
	public static void executa(String [] args)
	{
	//aplica o algoritmo ao arquivo recebido como parametro no quarto parametro (args[3]), 
	//pois o primeiro é a string rmi, o segundo é o nome do metodo e o terceiro o id da tarefa 
	//grava os resultados obtidos em arquivo, cada tarefa deve usar um nome de arquivo diferente 
	//para não ter problemas de duas tarefas escreverem no mesmo arquivo em um mesmo instante
 
	//retorna o status de fim da tarefa via rmi:
		//args[0]:string rmi
		//args[1]:comando executa
		//args[2]:id tarefa
		//args[3]:tarefa
 
		try
		{
			int iTarefa = Integer.parseInt(args[2]);
			System.out.println ("passou 1");
//--------------------------------------------------------------------------------------------------------
//tarefa a ser realizada
 
 
			Thread.sleep(10000);
			System.out.println("Tarefa: " + args[3] + "  id: " + iTarefa );
 
 
//--------------------------------------------------------------------------------------------------------
 
			//envio via rmi
			InterfaceGerente h = (InterfaceGerente) Naming.lookup(args[0]);
			Boolean status = h.tarefa(iTarefa, true);
		}
		catch (Exception e)
		{
			System.out.println ("Erro: " + e);
		}
 
	//se necessário particionar novamente o arquivo, pode ser util repassar a tarefa de volta para o programa gerente 
	//de forma que ela possa ser redistribuída nos nodos, isso pode ser feito chamando o metodo rmi utiizado no 
	//metodo inicia ivez de utilizar o metodo acima, mas apenas um dos dois pode ser usado.
 
	}
}
ipar/modelo.1195500546.txt.gz · Last modified: 2007/11/19 17:29 by ipar
Recent changes RSS feed Creative Commons License Donate Driven by DokuWiki