Baixe o app para aproveitar ainda mais
Prévia do material em texto
Universidade Federal de Ouro Preto - UFOP Departamento de Computação e Sistemas - DECSI CSI437 – Sistemas Operacionais Prof. Samuel Brito Processos Referência: Capítulo 3 do livro Sistemas Operacionais com Java (7ª edição) 2 Introdução • Os primeiros computadores permitiam que apenas um programa fosse executado por vez. – Total controle do sistema e acesso a todos os recursos do sistema. • Os computadores atuais permitem que vários programas sejam carregados na memória e executados concorrentemente. – Qual a diferença entre execução concorrente e execução paralela? – Qual/Quais técnica(s) permite(m) a execução concorrente dos programas? • Processos de usuário e processos do sistema operacional podem ser executados de forma concorrente. – CPU alterna entre processos, tornando o computador mais produtivo. 3 Conceito de Processo • Como são caracterizadas as atividades da CPU? – Sistema batch: jobs. – Sistema de tempo compartilhado: programas de usuário ou tarefas. • De certa forma, essas atividades são semelhantes: processos. • O que é um processo? – Um programa em execução. – Processo vs Programa. • Programa = seção de texto (geralmente, um arquivo executável). • Quando um programa vira um processo? 4 Conceito de Processo • Processo é uma entidade ativa: – Contador de Programa (Program Counter) e outros registradores. – Pilha de processo com dados temporários: • Parâmetros de método, endereço de retorno, variáveis locais, etc.) – Seção de dados: • Variáveis globais. – Heap: • Memória alocada dinamicamente. 5 Conceito de Processo 6 Conceito de Processo • Dois processos podem estar associados ao mesmo programa. – Duas sequências de execução separadas. – Exemplos: • Execução de várias janelas de um navegador Web. • Vários documentos do Word abertos simultaneamente. • Dois ou mais terminais (shell, linha de comando) abertos. – Seções de texto são equivalentes, mas as seções de dados, heap e pilha variam. • Também é comum haver um processo que gera muitos outros processos ao ser executado. 7 Estado do Processo • Enquanto um processo é executado, ele muda de estado: – Novo (New): • Processo está sendo criado. – Executando (Running): • As instruções estão sendo executadas. – Esperando (Waiting): • O processo está esperando algum evento. – Término de E/S ou recebimento de algum sinal. – Pronto (Ready): • O processo está esperando para ser atribuído a um processador. – Terminado (Terminated): • O processo terminou sua execução. 8 Estado do Processo • Nomes dos estados podem variar entre os sistemas operacionais. – Porém, os estados que eles representam são encontrados em todos os sistemas. • Apenas um processo pode estar executando em algum processador a cada instante. – Muitos processos podem estar prontos ou esperando. 9 Estado do Processo 10 Bloco de Controle de Processo • Cada processo é representado no sistema operacional por um Bloco de Controle de Processo (Process Control Block - PCB). – Informações associadas a um processo específico. • Informações contidas no PCB: – Estado do processo: • Estados vistos no slide anterior. – Contador de programa: • Indica o endereço da próxima instrução a ser executada para esse processo. – Registradores da CPU: • Depende da arquitetura do computador. Pode incluir acumuladores, índices, ponteiros de pilha, etc. • Tal informação precisa ser salva quando uma interrupção ocorre. 11 Bloco de Controle de Processo • Informações contidas no PCB (cont.): – Informação de escalonamento de CPU: • Prioridade do processo, ponteiros para filas de escalonamento e outros parâmetros relacionados ao escalonamento. – Informação de gerência de memória: • Informações como o valor dos registradores base e limite e as tabelas de página ou segmento. – Informação contábil: • Inclui informações sobre quantidade de CPU e tempo de leitura utilizado, limites de tempo, números de tarefa ou processo, etc. – Informação de status de E/S: • Lista de dispositivos de E/S alocados ao processo, lista de arquivos abertos, etc. 12 Bloco de Controle de Processo • O PCB serve como um repositório para quaisquer informações que possam variar de um processo para outro. Estado do processoEstado do processo Número do processoNúmero do processo Contador de programaContador de programa RegistradoresRegistradores Limites de memóriaLimites de memória Lista de arquivos abertosLista de arquivos abertos ...... 13 Alternando a CPU entre Dois Processos 14 PCB no Linux • O PCB é representado pela estrutura task_struct: 15 Threads • O modelo de processo discutido até agora sugere que um processo é um programa que executa apenas uma thread. – Exemplo: • Processo executando um programa de proessamento de texto. • Única thread executando: – Uma tarefa por vez. – Usuário não pode digitar caracteres e executar, simultaneamente, o corretor ortográfico dentro do mesmo processo. 16 Threads • Sistemas operacionais estenderam o conceito de processo para permitir que um processo tenha múltiplos threads de execução. – Desempenhar mais de uma tarefa de cada vez. • Benéfico em sistemas multiprocessados. • Em um sistema que suporta threads, o PCB é expandido de modo a incluir informações para cada thread. ESCALONAMENTO DE PROCESSOS Processos 18 Escalonamento de Processos • Qual é o objetivo da multiprogramação? – Fazer com que a CPU esteja executando algum processo o tempo todo. • Qual é o objetivo do compartilhamento de tempo? – Alternar a CPU entre processos com tanta frequência que os usuários possam interagir com cada programa enquanto ele está sendo executado. • Como atender os dois objetivos? – Escalonador de processos (Process Scheduler). • Seleciona um processo disponível (pronto) para a execução na CPU. • A partir de um conjunto de processos (fila). 19 Filas de Escalonamento • Fila de tarefas: – Conjunto de todos os processos do sistema. • Fila de prontos: – Todos os processos em memória principal, aguardando apenas pelo escalonamento da CPU. • Fila de dispositivo: – Conjunto de processos esperando por um dispositivo de E/S. 20 Fila de Prontos e de Dispositivos 21 Escalonamento de Processos • Inicialmente, um novo processo é inserido na fila de prontos. • Quando a CPU é alocada ao processo (estado executando), um dos seguintes eventos pode ocorrer: – O processo pode emitir uma solicitação de E/S, sendo inserido em uma fila de dispositivos. – O processo pode criar um novo processo-filho e esperá-lo terminar. – O processo pode ser removido à força da CPU, como resultado de uma interrupção, e ser devolvido à fila de prontos. • Quais as mudanças de estado ocorridas nos três eventos anteriores? 22 Representação do Escalonamento de Processos 23 Escalonadores • Um processo migra entre as diferentes filas de escalonamento no decorrer do seu tempo de vida. – Sistema operacional precisa selecionar os processos dessas filas. – O processo de seleção é executado pelo escalonador apropriado. 24 Tipos de Escalonadores • Escalonador de longo prazo: – Escalonador de tarefas. – Seleciona os processos a serem inseridos na fila de prontos. • Define o grau de multiprogramação. – Não é chamado com grande frequência. • Segundos, minutos. • Pode ser lento. 25 Tipos de Escalonadores • Escalonador de curto prazo: – Escalonador de CPU. – Seleciona qual o próximo processo a ser executado e aloca a CPU. – Chamado com alta frequência. • Milissegundos. • Precisa ser rápido. 26 Tipos de Escalonadores • Escalonador de médio prazo: – Usado em sistemas de tempo compartilhado.– Às vezes pode ser vantajoso remover processos da memória. • E da disputa ativa pela CPU. • Reduzir o grau de multiprogramação. – Mais tarde, o processo pode ser reintroduzido na memória e sua execução pode continuar de onde parou. – Útil quando a memória principal disponível está cheia. – Também conhecido como Swapping. 27 Escalonador de Médio Prazo 28 Descrição de Processos • De acordo com a característica de cada processo, o escalonador de longo prazo pode fazer uma seleção cuidadosa de quais processos serão inseridos na fila de prontos. • Processos podem ser descritos como: – Limitados por E/S (I/O bound): • Gastam mais tempo com E/S do que com uso de CPU. • Muitas rajadas curtas de processamento. – Limitados por CPU (CPU bound): • Gastam mais tempo com uso de CPU. • Períodos longos de processamento na CPU. 29 Descrição de Processos • É importante que o escalonador de longo prazo selecione um bom mix de processos, formado de processos limitados por E/S e limitados por CPU. – O que aconteceria se todos os processos selecionados fossem limitados por E/S? • Fila de prontos ficaria, quase sempre, vazia. • Escalonador de curto prazo não terá muito trabalho. – O que aconteceria se todos os processos selecionados fossem limitados por CPU? • Fila de dispositivos ficaria, quase sempre, vazia. • Dispositivos não seriam usados. • Sistema desbalanceado. 30 Troca de Contexto • Interrupções fazem com que o S.O. pare a execução de uma tarefa na CPU e execute uma rotina do kernel. – Interrupções ocorrem com frequência. • Quando ocorre uma interrupção, o sistema precisa salvar o contexto atual do processo que está em execução na CPU. – Mais tarde será necessário restaurar esse contexto. – Contexto é representado no PCB do processo. • Valor de registradores da CPU. • Estado do processo. • Informações de gerência de memória. 31 Troca de Contexto • Troca de contexto: – Troca de processos em execução na CPU. • Salva o estado atual do processo em execução. • Carrega o estado do novo processo. • Qual a desvantagem da troca de contexto? – Tempo de troca de contexto é puramente custo adicional (overhead). • O sistema operacional não realiza nenhum trabalho útil durante a troca. • Tempo gasto varia de um computador para outro. – Velocidade de memória, número de registradores que precisam ser copiados, etc. • Tempo também depende do suporte de hardware. • Quantidade de tempo gasto: – Alguns milissegundos. 32 Troca de Contexto OPERAÇÕES SOBRE PROCESSOS Processos 34 Operações Sobre Processos • Processos podem ser executados de forma concorrente. – Podem ser criados e removidos dinamicamente. • É responsabilidade do S.O. prover um mecanismo para criação e término de processo. 35 Criação de Processos • Um processo pode gerar diversos novos processos. – Como? • Chamada de sistema. • O processo que criou os novos processos é chamado processo pai. – Os novos processos são chamados filhos. – Cada processo filho pode gerar outros processos. • Árvore de processos. • Como identificar cada processo? – Identificador de processo (pid). • Identificador exclusivo. • Normalmente é um valor inteiro. 36 Árvore de Processos no Solaris 37 Criação de Processos • Processos necessitam de recursos para realizar sua tarefa. • Compartilhamento de recursos: – Pai e filhos compartilham todos os recursos. – Filhos compartilham parte dos recursos do pai. – Pai e filhos não compartilham recursos. • Recursos obtidos diretamente do S.O. • Processo pai pode passar dados de inicialização (entrada) para processos filhos. – Exemplo: • Passagem de parâmetros para um programa executado por linha de comando. 38 Criação de Processos • Possibilidades de execução quando são criados processos filhos: – O pai continua a ser executado simultaneamente com seus filhos. – O pai espera até que algum ou todos os seus filhos tenham terminado. 39 Criação de Processos • Possibilidades em termo de espaços de endereço do novo processo: – Processo filho é uma duplicata do processo pai. • Mesmo programa e dados do pai. – Processo filho tem um novo programa carregado nele. 40 Criação de Processos no UNIX/LINUX • Cada processo tem seu PID (inteiro exclusivo). • Um novo processo é criado pela chamada de sistema fork( ). – O novo processo consiste em uma cópia do espaço de endereços do processo original. • Processo pai se comunica facilmente com seu filho. • Os dois processos continuam a execução após o fork(), com uma diferença: – O código de retorno é zero para o novo processo (filho). – O identificador de processo do filho é retornado ao pai. 41 Criação de Processos no UNIX/LINUX • A chamada de sistema exec( ) é usada após uma chamada de sistema fork( ) por um dos dois processos para substituir o espaço de memória do processo por um novo programa. – exec( ) carrega um arquivo binário na memória e inicia sua execução. • Destruindo a imagem de memória contida no processo. • Processo pai pode continuar sua execução ou aguardar (chamada wait( )) para sair da fila de prontos até que a execução do filho termine. 42 Criação de Processos no UNIX/LINUX 43 Criação de Processos no UNIX/LINUX (pid > 0) (pid = 0) 44 Término de Processo • Um processo é encerrado quando termina a execução de seu último comando e solicita ao S.O. que o exclua, usando a chamada de sistema exit( ). – O processo pode retornar um valor de status (inteiro) ao seu processo pai. • Todos os recursos do processo são desalocados pelo sistema operacional. – Memória física e virtual, arquivos abertos, buffers de E/S, ... • O término também pode ocorrer em outras circunstâncias: – Um processo pode causar o término do outro por meio de uma chamada de sistema apropriada. • Normalmente só pode ser invocada pelo pai do processo que deve ser terminado. – Por que? 45 Término de Processo • Um processo pai pode terminar a execução de um de seus filhos por diversos motivos: – O filho ultrapassou seu uso de alguns dos recursos alocados a ele. – A tarefa atribuída ao filho não é mais necessária. – O pai está sendo encerrado. • S.O. não permite que um filho continue se seu pai terminar. • Terminação em cascata. 46 Término de Processo • No encerramento normal de um processo, exit( ) pode ser chamada diretamente ou indiretamente (comando return no main). • Um processo-pai pode esperar o encerramento de um processo-filho usando a chamada de sistema wait( ). – Parâmetro: salva o status de saída do filho. – Retorno: identificador do processo encerrado. COMUNICAÇÃO ENTRE PROCESSOS Processos 48 Comunicação entre Processos • Um processo executando no sistema operacional pode ser: – Independente: • Se não puder afetar ou ser afetado pelos outros processos em execução. • Qualquer processo que não compartilhe dados com qualquer outro processo. – Cooperativo: • Se puder afetar ou ser afetado por outros processos em execução. • Qualquer processo que compartilhe dados com outros processos. 49 Comunicação entre Processos • Motivos para prover um ambiente que permita cooperação de processos: – Compartilhamento de informações: • Como diversos usuários podem estar interessados na mesma informação (por exemplo, um arquivo compartilhado), temos de prover um ambiente para permitir o acesso concorrente a tais informações. – Agilidade na computação: • Podemos dividir uma tarefa em subtarefas (execução paralela), a fim de que ela seja executada de forma rápida. • Quando é possível obter a agilidade na computação de uma tarefa? – Se o computador tiver vários elementos de processamento (CPUs e canais deE/S). 50 Comunicação entre Processos • Motivos para prover um ambiente que permita cooperação de processos (cont.): – Modularidade: • Construção de um sistema operacional de forma modular, dividindo as funções em processos ou threads separadas. – Conveniência: • Um único usuário pode querer trabalhar em muitas tarefas ao mesmo tempo. • Exemplo: – Um usuário pode estar editando um arquivo, ouvindo música e compilando um programa em paralelo. 51 Comunicação entre Processos • Processos cooperativos precisam de mecanismos de comunicação entre processos (Interprocess Communication – IPC) que lhes permitam a troca de dados e informações. • Existem dois modelos fundamentais de comunicação entre processos: – Memória compartilhada: • Uma região de memória que é compartilhada pelos processos cooperativos é estabelecida. – Por que é necessário estabelecer essa região? Como isso é feito? • Processos podem trocar informações por meio da leitura e/ou escrita de dados da área compartilhada. – Troca de mensagem: • Comunicação ocorre por meio de mensagens trocadas entre os processos cooperativos. 52 Comunicação entre Processos Troca de mensagens Mem. Compartilhada 53 Comunicação entre Processos • Os dois modelos de comunicação são comuns nos sistemas operacionais modernos. – Muitos sistemas operacionais implementam ambos. • Vantagens da troca de mensagens? – Útil para trocar quantidades menores de dados. • Nenhum conflito precisa ser evitado. – Mais fácil de implementar do que a memória compartilhada. – Mais fácil de implementar em um sistema distribuído. • Vantagens da memória compartilhada? – Permite velocidade máxima e conveniência de comunicação. – Menos chamadas de sistema para efetuar comunicação. • Somente para estabelecer a região de memória compartilhada. • Restante dos acessos são tratados como acessos à memória. 54 Sistemas de Memória Compartilhada • A comunicação entre processos usando memória compartilhada requer a comunicação dos processos para estabelecer uma região de memória compartilhada. – Região reside no espaço de endereços de um processo. • Demais processos podem “se conectar” a esse espaço. • O S.O. tenta impedir que um processo acesse a memória de outro processo. – Memória compartilhada exige que dois ou mais processos concordem em remover essa restrição. • Formato de dados e local são determinados pelos processos cooperativos. – Não estão sob controle do S.O. – Processos são responsáveis por garantir que não estarão escrevendo no mesmo local simultaneamente. 55 Sistemas de Memória Compartilhada • Para ilustrar o conceito de processos cooperativos, considere o problema do produtor-consumidor. – Paradigma comum para os processos cooperativos. • Um processo produtor produz informações consumidas por um processo consumidor. – Exemplo: • Compilador pode produzir código assembly que é consumido por um montador (assembler). O montador produz módulos objeto, que são consumidos pelo carregador. • Arquitetura cliente-servidor. Servidor é um produtor e clientes são consumidores. – Servidor Web fornece arquivos HTML e imagens que são lidos pelo navegador Web do cliente. 56 Sistemas de Memória Compartilhada • Uma solução para o problema do produtor-consumidor usa a memória compartilhada: – Criação de um buffer. • Produtor e consumidor são executados concorrentemente. • Produtor preenche o buffer com itens. • Consumidor remove um item por vez do buffer para processá-lo. – O buffer deve residir na área de memória que é compartilhada pelos processos produtor e consumidor. • Produtor pode produzir um item enquanto consumidor está processando outro. • Problema? – Necessidade de sincronização. » Consumidor não pode tentar consumir um item que ainda não foi produzido. 57 Sistemas de Memória Compartilhada • Dois tipos de buffer podem ser usados: – Buffer ilimitado (unbounded buffer) • Não coloca um limite prático no tamanho do buffer. – Vector em C++ ou Java. • Consumidor precisa esperar a produção de novos itens. • Produtor sempre pode produzir novos itens. – Buffer limitado (bounded buffer) • Tamanho do buffer é fixo. – Alocação estática. • Consumidor precisa esperar a produção de novos itens. • Produtor precisa esperar se o buffer estiver cheio. 58 Solução com Buffer Limitado e Memória Compartilhada • Interface para implementações de buffer: 59 Solução com Buffer Limitado e Memória Compartilhada 60 Solução com Buffer Limitado e Memória Compartilhada 61 Solução com Buffer Limitado e Memória Compartilhada • Processo produtor chama o método insert quando deseja inserir um item no buffer. • Processo consumidor chama o método remove quando quer consumir um item do buffer. 62 Solução com Buffer Limitado e Memória Compartilhada 63 Solução com Buffer Limitado e Memória Compartilhada • Nessa solução, tanto produtor quanto consumidor serão bloqueados quando o buffer não puder ser utilizado por eles. – Necessidade de sincronismo entre processos. 64 Sistema de Troca de Mensagens • Troca de mensagens é outra maneira de manter comunicação entre processos. – Sistemas operacional fornece os meios para que os processos cooperativos se comuniquem entre si. – Sem compartilhar o mesmo espaço de endereços. • Útil em ambiente distribuído, no qual os processos em comunicação podem residir em diferentes computadores, conectados por uma rede. – Exemplo: • Um aplicativo de bate-papo. – Comunicação envolve troca de mensagens. 65 Sistema de Troca de Mensagens • Um sistema de troca de mensagens fornece pelo menos duas operações básicas: – Send: • Enviar uma mensagem. – Receive: • Receber uma mensagem. • Mensagens podem ter um tamanho fixo ou variável. – Utilização de mensagens de tamanho fixo torna a implementação mais simples. 66 Sistema de Troca de Mensagens • Se os processos P e Q desejam se comunicar, eles precisam enviar e receber mensagens um do outro. – É necessário haver um enlace de comunicação entre eles: • Comunicação direta ou indireta • Comunicação síncrona ou assíncrona • Buffer automático ou explícito 67 Sistema de Troca de Mensagens • Processos precisam ter um modo de se referir uns aos outros. – Comunicação direta: • Cada processo que deseja se comunicar precisa nomear explicitamente o destinatário ou emissor da comunicação. – send(P, mensagem): envia mensagem para o processo P. – receive(Q, mensagem): recebe mensagem do processo P. • Enlace é estabelecido automaticamente entre cada par de processos que desejam se comunicar. • Um único canal exclusivo para cada par de processos. 68 Sistema de Troca de Mensagens – Comunicação indireta: • As mensagens são enviadas e recebidas de caixas de correio. – Cada caixa de correio tem um identificador único. – send(A, mensagem): enviar uma mensagem à caixa de correio A. – receive(A, mensagem): receber uma mensagem da caixa de correio A. • Processos só podem se comunicar se compartilharem uma caixa de mensagens. • Canal é estabelecido se os processos compartilham uma caixa de mensagem. – Um canal pode ser associado com vários processos. – Cada par de processo pode compartilhar diversos canais de comunicação. 69 Sistema de Troca de Mensagens – Comunicação indireta (cont.): • Compartilhamento de caixa de correio. – P1, P2, e P3 compartilham a caixa de correio A. – P1, envia mensagem. – P2 e P3 executam o receive ao mesmo tempo. – Quem ficou com a mensagem? • Soluções: – Permitir que um link só possa ser associado a no máximo dois processos. – Permitir que apenas um processo execute o receive em um dado instante. – Permitir que o sistema escolhaarbitrariamente o receptor e notificar o emissor da escolha. 70 Sistema de Troca de Mensagens • Implementações das primitivas send e receive: – Bloqueante • Síncrona. • send bloqueante faz o emissor esperar até que a mensagem seja recebida. • receive bloqueante faz o receptor esperar até que uma mensagem esteja disponível. – Não bloqueante • Assíncrona. • send não bloqueante faz o emissor enviar a mensagem e continuar sua execução. • receive não bloqueante faz o receptor receber uma mensagem válida ou nula. 71 Sistema de Troca de Mensagens • Seja comunicação direta ou indireta, bloqueante ou não bloqueante, as mensagens trocadas pelos processos em comunicação residem em uma fila temporária. • Essas filas podem ser implementadas de três maneiras: – Capacidade zero: • A fila tem o tamanho máximo de zero. • Um enlace não pode ter quaisquer mensagens aguardando. • Emissor precisa ser bloqueado até o destinatário receber a mensagem. 72 Sistema de Troca de Mensagens – Capacidade limitada: • A fila possui tamanho finito. • Se a fila não estiver cheia, a nova mensagem é colocada na fila e o emissor pode continuar a execução sem esperar. • Se a fila estiver cheia, o emissor terá de ser bloqueado até haver espaço disponível na fila. – Capacidade ilimitada: • A fila potencialmente possui tamanho infinito. • Qualquer quantidade de mensagens poderá esperar nela. • Emissor nunca é bloqueado. 73 Sistema de Troca de Mensagens • Solução do problema do produtor-consumidor utilizando a troca de mensagens: 74 Sistema de Troca de Mensagens • Caixa de correio para troca de mensagens: 75 Sistema de Troca de Mensagens • Processo produtor: 76 Sistema de Troca de Mensagens • Processo consumidor: 77 Dúvidas? Slide 1 Introdução Conceito de Processo Conceito de Processo Conceito de Processo Conceito de Processo Estado do Processo Estado do Processo Estado do Processo Bloco de Controle de Processo Bloco de Controle de Processo Bloco de Controle de Processo Alternando a CPU entre Dois Processos PCB no Linux Threads Threads Escalonamento de processos Escalonamento de Processos Filas de Escalonamento Fila de Prontos e de Dispositivos Escalonamento de Processos Representação do Escalonamento de Processos Escalonadores Tipos de Escalonadores Tipos de Escalonadores Tipos de Escalonadores Escalonador de Médio Prazo Descrição de Processos Descrição de Processos Troca de Contexto Troca de Contexto Troca de Contexto Operações sobre processos Operações Sobre Processos Criação de Processos Árvore de Processos no Solaris Criação de Processos Criação de Processos Criação de Processos Criação de Processos no UNIX Criação de Processos no UNIX Criação de Processos no UNIX Criação de Processos no UNIX Término de Processo Término de Processo Término de Processo Comunicação entre processos Comunicação entre Processos Comunicação entre Processos Comunicação entre Processos Comunicação entre Processos Comunicação entre Processos Comunicação entre Processos Sistemas de Memória Compartilhada Sistemas de Memória Compartilhada Sistemas de Memória Compartilhada Sistemas de Memória Compartilhada Solução com Buffer Limitado e Memória Compartilhada Solução com Buffer Limitado e Memória Compartilhada Solução com Buffer Limitado e Memória Compartilhada Solução com Buffer Limitado e Memória Compartilhada Solução com Buffer Limitado e Memória Compartilhada Solução com Buffer Limitado e Memória Compartilhada Sistema de Troca de Mensagens Sistema de Troca de Mensagens Sistema de Troca de Mensagens Sistema de Troca de Mensagens Sistema de Troca de Mensagens Sistema de Troca de Mensagens Sistema de Troca de Mensagens Sistema de Troca de Mensagens Sistema de Troca de Mensagens Sistema de Troca de Mensagens Sistema de Troca de Mensagens Sistema de Troca de Mensagens Sistema de Troca de Mensagens Dúvidas?
Compartilhar