Docsity
Docsity

Prepare-se para as provas
Prepare-se para as provas

Estude fácil! Tem muito documento disponível na Docsity


Ganhe pontos para baixar
Ganhe pontos para baixar

Ganhe pontos ajudando outros esrudantes ou compre um plano Premium


Guias e Dicas
Guias e Dicas


Como gerir processadores, Resumos de Web Design e Desenvolvimento

Gerencia de Processadores de alto rendimento

Tipologia: Resumos

2024

Compartilhado em 16/04/2026

vinicios-ximendes
vinicios-ximendes 🇧🇷

1 documento

1 / 55

Toggle sidebar

Esta página não é visível na pré-visualização

Não perca as partes importantes!

bg1
DEFINIÇÃO
Definição de processos e threads e da forma como esses elementos devem ser estruturados para a
construção de sistemas eficientes.
PROPÓSITO
Atualmente, até os mais simples dispositivos contam com a capacidade de multiprocessamento. Os
sistemas operacionais, acompanhando o rápido desenvolvimento da tecnologia, fornecem mecanismos
que possibilitam a construção de sistemas concorrentes que buscam tirar o máximo proveito desta
capacidade. Saber explorar esta possibilidade é fundamental para a formação de profissionais
habilitados a resolverem os desafios demandados por sistemas que buscam alto desempenho.
PREPARAÇÃO
Antes de iniciar o conteúdo deste tema, é desejável ter acesso a um computador (ou máquina virtual)
com Linux instalado. Para os exemplos deste tema, foi utilizado o Ubuntu Desktop 20.04 LTS.
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21
pf22
pf23
pf24
pf25
pf26
pf27
pf28
pf29
pf2a
pf2b
pf2c
pf2d
pf2e
pf2f
pf30
pf31
pf32
pf33
pf34
pf35
pf36
pf37

Pré-visualização parcial do texto

Baixe Como gerir processadores e outras Resumos em PDF para Web Design e Desenvolvimento, somente na Docsity!

DEFINIÇÃO

Definição de processos e threads e da forma como esses elementos devem ser estruturados para a construção de sistemas eficientes.

PROPÓSITO

Atualmente, até os mais simples dispositivos contam com a capacidade de multiprocessamento. Os sistemas operacionais, acompanhando o rápido desenvolvimento da tecnologia, fornecem mecanismos que possibilitam a construção de sistemas concorrentes que buscam tirar o máximo proveito desta capacidade. Saber explorar esta possibilidade é fundamental para a formação de profissionais habilitados a resolverem os desafios demandados por sistemas que buscam alto desempenho.

PREPARAÇÃO

Antes de iniciar o conteúdo deste tema, é desejável ter acesso a um computador (ou máquina virtual) com Linux instalado. Para os exemplos deste tema, foi utilizado o Ubuntu Desktop 20.04 LTS.

OBJETIVOS

MÓDULO 1

Descrever os conceitos de processos

MÓDULO 2

Compreender como ocorre a construção de programas concorrentes

MÓDULO 3

Identificar o mecanismo de comunicação entre processos

MÓDULO 4

Comparar as diferentes formas de escalonamento

Fonte: Shutterstock/whiteMocca

Para compilar um programa chamado prog.c basta entrar no shell, no diretório onde se encontra o programa, e executar o comando:

gcc prog.c

Será criado um arquivo executável de nome a.out.

Para compilar um programa e escolher o nome do arquivo executável que será gerado, utilize o parâmetro -o. Por exemplo, para compilar o programa prog.c e gerar como saída um arquivo executável prog , utilize o comando:

gcc prog.c -o prog

Para executar o programa prog que acabou de ser compilado, execute o comando:

./prog

MODELO DE PROCESSO

Os primeiros sistemas permitiam a execução de apenas um programa de cada vez, que deveria ter o controle completo do sistema e acesso a todos os seus recursos. Os sistemas atuais permitem que diversos programas sejam carregados na memória e executados simultaneamente.

Essa evolução tornou necessário um controle maior na divisão de tarefas dos vários programas, resultando na noção de processo.

Em um sistema multiprogramável , a unidade central de processamento (UCP) alterna entre processos, dedicando um pouco de seu tempo a cada um, dando a ilusão de paralelismo. Este esquema costuma ser chamado de pseudoparalelismo.

SISTEMA MULTIPROGRAMÁVEL

Sistema que permite a execução de mais de um programa ao mesmo tempo.

Neste modelo, todo software executado no computador é organizado em processos sequenciais , também chamado de processos. O modelo de processos foi desenvolvido para tornar o paralelismo mais fácil de tratar.

Um processo é um programa em execução, incluindo os valores atuais dos registradores e variáveis, assim como seu espaço de endereçamento. Um programa por si só não é um processo, mas uma

entidade passiva. Um processo é uma entidade ativa, com um contador de instruções e um conjunto de registradores a ele associado.

ESPAÇO DE ENDEREÇAMENTO

Conjunto de endereços de memória que um processo pode acessar.

CONTADOR DE INSTRUÇÕES

Registrador de uma unidade central de processamento que indica qual é a posição atual na sequência de execução de um processo. Dependendo dos detalhes da arquitetura, ele armazena o endereço da instrução que está sendo executada ou o endereço da próxima instrução.

 ATENÇÃO

Embora dois processos possam estar associados a um mesmo programa, são duas sequências de execução distintas.

Conceitualmente, cada processo tem sua própria UCP. Com a UCP alternando entre os processos, a velocidade com que um processo executa não será uniforme.

Fonte: Yduqs/Acervo pessoal  Exemplo de sistema de tempo compartilhado com 4 processos concorrentes.

MULTIPROCESSADOR

Sistema com mais de um processador nos quais os processadores compartilham uma memória comum.

 ATENÇÃO

Em todos esses casos, um novo processo é criado por outro já existente, executando uma chamada de sistema de criação de processo. O que esse processo faz é executar uma chamada de sistema para criar o processo.

No Linux, a chamada de sistema mais comum para a criação de processos é a fork(). Essa chamada cria um processo idêntico ao processo que a chamou. Após a fork() , os dois processos, o pai e o filho, têm a mesma imagem de memória, as mesmas variáveis de ambiente e os mesmos arquivos abertos.

O código a seguir, em Linguagem C, exemplifica a criação de um novo processo com a chamada de sistema fork().

#include #include #include

int main() { int resultado, pid, ppid; resultado = fork(); if (resultado < 0) printf("Algo deu errado!!!\n"); pid = getpid(); if (resultado == 0) { ppid = getppid(); printf("Eu sou o processo filho, meu PID é %d e meu pai tem PID=%d.\n", pid, ppid); } if (resultado > 0) {

printf("Eu sou o processo pai, meu PID é %d e meu filho tem PID=%d.\n", pid, resultado); waitpid(resultado, NULL, 0); } }

Quando fork() é executada, o resultado do processamento é armazenado na variável “resultado”. O processo pai (que fez a chamada) receberá na variável “resultado” o PID do processo filho, enquanto o processo filho receberá na variável “resultado” o valor 0. Assim, para saber quem é o processo pai e quem é o processo filho, é necessário verificar o valor em “resultado”.

PID

Abreviação de Process ID (identificação do processo). É um valor que identifica um processo de forma única no sistema operacional.

De início, verifica-se a ocorrência de algum erro na criação do processo filho. Caso tenha ocorrido um erro, “resultado” receberá um valor negativo.

A seguir, o comando “pid = getpid();” obtém o PID do processo corrente.

Então, o processo verifica o valor de “resultado”. Se for zero, é o processo filho que está executando e, nesse, caso o processo executa “ppid = getppid();” para obter o PID do processo pai. Se o valor de “resultado” for maior que zero, significa que quem está executando é o processo pai. Ambos (pai e filho) mostram na tela os respectivos PID.

Por fim, o processo pai executa a chamada de sistema “waitpid(resultado, NULL, 0);” para, antes de terminar, aguardar o término da execução do filho.

Quando o fork() é utilizado para a criação de um processo que executará o código de outro programa, a chamada de sistema execve() deve ser utilizada para que o processo filho mude sua imagem de

O processo também pode terminar quando descobre um erro fatal. Ele pode solicitar ao usuário uma nova entrada de dados ou simplesmente encerrar sua execução de maneira similar à saída normal.

Saída por erro (voluntária)

Outra razão para o término é um erro causado pelo processo, muitas vezes decorrente de um erro de programa. Exemplos incluem executar uma instrução ilegal, referenciar uma memória não existente ou dividir por zero.

Morto por outro processo (involuntário)

A quarta razão pela qual um processo pode ser finalizado é a execução de uma chamada de sistema dizendo ao sistema operacional para matar outro processo. Para um processo matar outro, é necessário autorização.

Em alguns sistemas, quando um processo é finalizado, todos os processos que ele criou são finalizados também. Nem o Linux nem o Windows funcionam desta forma.

HIERARQUIA DE PROCESSOS

Em alguns sistemas, quando um processo cria outro, o processo pai e o processo filho continuam associados. O processo filho pode criar mais processos, formando uma hierarquia de processos. No Linux, um processo e todos os seus filhos e demais descendentes formam um grupo de processos.

No Linux, um processo especial chamado systemd (ou init , dependendo da versão) está presente na imagem de inicialização do sistema. É o primeiro processo a ser executado e é responsável por iniciar a execução dos demais processos do sistema operacional. Cada um desses processos pode iniciar mais processos. Desse modo, todos os processos no Linux pertencem a uma única árvore, com o systemd (ou init ) em sua raiz.

Fonte: Shutterstock/jivacore

A imagem a seguir exemplifica a árvore de processos em um sistema Linux por meio da execução do comando “ pstree ”.

systemd-+-ModemManager---2[{ModemManager}] |-NetworkManager---2[{NetworkManager}] |-VBoxService---8[{VBoxService}] |-accounts-daemon---2[{accounts-daemon}] |-acpid |-avahi-daemon---avahi-daemon |-colord---2[{colord}] |-cron |-cups-browsed---2[{cups-browsed}] |-cupsd |-dbus-daemon |-gdm3-+-gdm-session-wor-+-gdm-wayland-ses-+-gnome-session-b---3[{gnome-session-b}] | | | -2*[{gdm-wayland-ses}] | |-2[{gdm-session-wor}] | -2*[{gdm3}] |-2*[kerneloops] |-login---bash---pstree |-networkd-dispat |-polkitd---2*[{polkitd}] |-rsyslogd---3*[{rsyslogd}] |-rtkit-daemon---2*[{rtkit-daemon}] |-snapd---8*[{snapd}] |-switcheroo-cont---2*[{switcheroo-cont}] |-systemd---(sd-pam) |-systemd-+-(sd-pam) | |-at-spi-bus-laun-+-dbus-daemon | |-3[{at-spi-bus-laun}] | |-at-spi2-registr---2[{at-spi2-registr}] | |-dbus-daemon | |-gjs---4[{gjs}] | |-gnome-keyring-d---3[{gnome-keyring-d}] | |-gnome-session-b---3[{gnome-session-b}] | |-gnome-session-c---{gnome-session-c} | |-gnome-shell-+-Xwayland | | |-ibus-daemon-+-ibus-engine-sim---2[{ibus-engine-sim}] | | | |-ibus-memconf---2*[{ibus-memconf}]

|-whoopsie---2*[{whoopsie}] `-wpa_supplicant

ESTADOS DE PROCESSOS

Eventualmente, um processo que está em execução necessita parar momentaneamente sua execução por estar aguardando uma informação ainda não disponível ou porque já foi executado por muito tempo e precisa liberar a UCP para outro processo.

Um processo pode transitar por diferentes estados, que dependem do sistema operacional. De forma geral, podemos dizer que um processo pode estar nos estados novo, executando, pronto, bloqueado ou terminado.

Fonte: Yduqs/Acervo pessoal

Quando um processo é criado, ele se inicia no estado novo. O processo já existe, mas ainda precisam ser tomadas algumas providências pelo sistema operacional para que o processo possa iniciar sua execução. Quando tudo está pronto, o processo faz a transição 1 e muda para o estado pronto.

O processo reúne todas as condições para ser executado quando está no estado pronto , faltando apenas que o processador fique disponível para sua execução. Quando um processador fica disponível e o processo é selecionado para execução, ele faz a transição 2 e vai para o estado executando.

No estado executando , o processo tem suas instruções executadas pelo processador e três coisas podem acontecer:

  1. A primeira delas é o processo ser executado por muito tempo. Então, o sistema operacional interrompe momentaneamente a execução do processo para colocar outro em seu lugar, ocorrendo a transição 3, que leva o processo de volta ao estado pronto , no qual aguardará nova oportunidade de execução.
  2. Pode ocorrer ainda de o processo solicitar uma operação de entrada e saída e ter de aguardar a conclusão da operação, que costuma ser demorada quando comparada à capacidade de

processamento do processador de um computador. Nesse caso, ocorre a transição 4, e o processo vai para o estado bloqueado.

  1. Por último, o processo pode encerrar sua execução, realizando a transição 6 e indo para o estado terminado.

O processo que vai para o estado bloqueado permanece nele até que seja concluída a operação que aguardava. Quando isso ocorre, o processo passa pela transição 5 e vai para o estado pronto até ser novamente selecionado para execução.

 ATENÇÃO

O estado terminado é para os processos que não serão mais executados. Quando está neste estado, o sistema operacional deve providenciar a desalocação dos recursos que ainda estejam alocados ao processo. Somente após a desalocação de todos os recursos, o processo deixa de existir no sistema.

Para implementar o modelo de processos, o Linux mantém uma tabela de processos, com uma entrada por processo. Esta entrada é chamada de Bloco de Controle de Processo – BCP ( Process Control Block – PCB) e contém todas as informações do processo. Algumas entradas do BCP são:

Estado do processo

Prioridade do processo

Número do processo

Registradores da UCP

Informações relativas ao gerenciamento de memória

Informações de contabilidade

Informações sobre operações de E/S

Essa visão dá origem ao seguinte modelo:

Fonte: Yduqs/

O nível mais baixo do sistema operacional é o escalonador (também conhecido como agendador ). Ele cuida do gerenciamento de interrupções e dos detalhes de como iniciar e parar processos. Também costuma ser muito pequeno.

PROCESSOS NO LINUX

Os processos no Linux comportam-se como processos sequenciais tradicionais. É um sistema operacional multiusuário/multitarefa, que permite a execução simultânea de diversos processos, que podem pertencer a diferentes usuários. Mesmo que haja apenas um usuário logado no sistema, é comum a existência de diversos daemons em execução.

Fonte: Shutterstock/Paolo De Gasperis

 ATENÇÃO

Um exemplo é o daemon de impressão, responsável por fazer a alocação da impressora e controlar o envio de trabalhos de impressão. É uma parte importante do sistema, pois permite o compartilhamento da impressora por diversos processos, possivelmente pertencentes a diferentes usuários.

A forma usual para criação de processos no Linux ocorre por meio da chamada de sistema fork() , conforme você já estudou neste tema.

O processo filho recebe uma cópia exata do espaço de endereçamento do processo pai. Todos os valores de variáveis e demais objetos em memória serão idênticos, porém alterações realizadas por um dos processos em qualquer conteúdo de memória não afetarão o outro.

Arquivos que foram abertos antes da chamada fork() permanecem abertos para o processo pai e para o processo filho. As alterações realizadas por qualquer um destes processos se tornam imediatamente disponíveis para o outro. Processos são identificados por um número inteiro conhecido como PID (identificação do processo).

Algumas chamadas de sistema do Linux para o gerenciamento de processos são:

Chamada de sistema

Descrição

fork() Cria um processo filho idêntico ao processo pai. Para o processo pai, retorna o PID do processo filho e, para o processo filho, retorna o valor 0.

waitpid() Espera até que o processo filho passado como parâmetro termine sua execução.

execve()

Substitui a imagem de execução de um processo, fazendo com que, no lugar do processo corrente, seja executado o código do programa passado como parâmetro.

exit() Termina a execução do processo e retorna como^ status^ o valor passado como parâmetro.

Faça o download do documento Comandos do Shell , com os principais comandos para Linux.

PROCESSOS NO LINUX.

GABARITO

1. Uma das formas de criação de subprocessos no Linux ocorre por meio da chamada de sistema fork(). Assinale a alternativa verdadeira em relação à chamada de sistema fork().

A alternativa "B " está correta.

A chamada de sistema fork() cria um subprocesso que é cópia exata do processo pai, mas que compartilha com ele apenas os arquivos abertos. Portanto, não há compartilhamento do espaço de endereçamento com o processo pai. Para executar o código de outro programa, é necessário utilizar a chamada de sistema execve() após a chamada de sistema fork().

2. É comum um processo transitar por vários estados durante sua vida em um sistema operacional. Sobre os estados de um processo, é correto afirmar que:

A alternativa "D " está correta.

Um processo no estado bloqueado está aguardando a ocorrência de um evento que fará com que ele possa prosseguir sua execução. Quando ocorrer este evento, o processo deverá ir obrigatoriamente para a fila de processos prontos, onde aguardará a liberação de uma UCP antes de poder entrar em execução.

MÓDULO 2

Compreender como ocorre a construção de programas concorrentes

SUBPROCESSO

Quando um processo (processo pai) cria um outro processo, ele é conhecido como subprocesso ou processo filho. O subprocesso, por sua vez, pode criar outros subprocessos.

A utilização de subprocessos permite dividir uma aplicação em partes que podem trabalhar de forma concorrente. Imagine, por exemplo:

 EXEMPLO

Um servidor web que aceite requisições de clientes da internet e coloque as requisições em uma fila. Uma forma simples de implementar este servidor seria criar um processo que pegue a primeira requisição da fila, processe a requisição e devolva o resultado do processamento ao cliente que a solicitou. Após isso, ele pegaria a próxima requisição e faria o mesmo trabalho.

O problema com essa solução é que ela não aproveita a capacidade de multiprocessamento dos sistemas atuais. Como existe apenas um processo em execução, somente um dos processadores do sistema é utilizado para atendimento das requisições. Além disso, se houver várias requisições complexas e demoradas e uma requisição simples, como uma pequena página HTML, entrar no final da fila, esta requisição mais simples, que poderia ser respondida rapidamente, será atendida somente depois que todas as demais forem processadas.

Fonte: Shutterstock/Adhil Jayan

A utilização de subprocessos resolve bem estes problemas. Se o servidor, no lugar de responder sequencialmente a cada requisição, criar um subprocesso para cada uma delas, tirará proveito da capacidade de multiprocessamento do sistema. Como cada requisição será tratada por um processo diferente , as requisições serão espalhadas pelos processadores do sistema, aproveitando sua capacidade de multiprocessamento. Além disso, como as requisições serão tratadas por diferentes processos, elas serão executadas concorrentemente.

Dessa forma, uma requisição simples, como a solicitação de uma página HTML, poderá ser iniciada e respondida rapidamente, ainda que existam outras requisições complexas solicitadas anteriormente e que elas ainda estejam sendo processadas.

O trecho de código abaixo em Linguagem C exemplifica a parte de um servidor web simples que cria subprocessos para atendimento das requisições: