podendo chegar inclusive a um unico processador. Muitas vezes e vantajoso expressar um programa como uma colecao de processos rodando em paralelo, desconsiderando o fato de que esses processos podem rodar simultaneamente. Essa tecnica, naturalmente, nao tem utilidade nas aplicacoes em que a busca pela reducao do tempo de processamento e o unico objetivo.Algumas linguagens escondem do programador essa distincao entre paralelismo real e pseudo paralelismo, fazendo com que o numero de processos rodando efetivamente, em um dado momento, seja totalmente desconhecido. Outras linguagens nao escondem essa distincao, permitindo, inclusive que o proprio programador atribua, explicitamente, determinadas partes do seu programa a determinadas unidades de processamento. Muitas vezes esse controle do mapeamento de processos em processadores e interessante, uma vez que aumenta a flexibilidade do sistema. Por exemplo, o programador pode utilizar variaveis compartilhadas na comunicacao de processos que, sabidamente, estao rodando em um mesmo processador ou atribuir um determinado processador a um determinado processo por alguma razao especial.Como sera visto a seguir, cada linguagem de programacao distribuida possui sua unidade de paralelismo que varia do processo a expressao Hansen (1995). A granularidade do paralelismo tambem varia de linguagem para linguagem e depende muito do custo de comunicacao apresentado pelo sistema de hardware distribuido envolvido. Por exemplo, um sistema distribuido fortemente acoplado, tal como o hipercubo, pode suportar eficientemente um paralelismo de granularidade fina. Por outro lado, um sistema de rede de longa distancia inviabilizaria uma computacao paralela com essa granularidade.Finalizando este preambulo, e interessante considerar as linguagens que nao suportam o controle explicito do paralelismo. Ao inves do programador efetuar a divisao do codigo do programa em segmentos paralelos, e o compilador que o faz. Algumas linguagens tambem nao permitem controle explicito da comunicacao entre processos. O envio de uma mensagem a um processo resulta na geracao implicita de um outro processo que gerencia essa comunicacao.4.6.1.1 Expressoes de ParalelismoA maneira como o paralelismo e expresso varia de linguagem para linguagem e depende muito da unidade do paralelismo adotado, que pode ser um processo, um objeto, um comando, uma expressao ou, ainda, uma clausula, Bal et al. (1989).Para a grande maioria das linguagens imperativas, destinada a programacao distribuida, o paralelismo encontra-se fundamentado na importante nocao de processo. Existem varias consideracoes a esse respeito, mas, em geral, um processo pode ser considerado como um processador logico que executa codigos sequencialmente e possui seu proprio estado e dados.A definicao de um processo dentro de um programa distribuido e semelhante a de um procedimento em um programa sequencial, havendo inclusive linguagens que permitem a definicao do tipo "processo".Uma vez definidos, os processos podem ser criados por duas maneiras bem distintas. Explicitamente, atraves de alguma construcao do tipo create, que lembra uma chamada de procedimento em um programa sequencial, com efeitos, todavia, totalmente diferentes. Enquanto que uma chamada de procedimento resulta apenas em um desvio do fluxo de execucao do programa, um create inicia a execucao de um novo processo, alocando-lhe um processador autonomo disponivel. A criacao implicita de um processo, por outro lado, e feita atraves da declaracao de uma variavel como sendo de um