·
Tecnologias da Informação e Comunicação ·
Sistemas Operacionais
· 2023/2
Send your question to AI and receive an answer instantly
Recommended for you
8
Lista 2 - 2023-2
Sistemas Operacionais
UFSC
6
Lista - Servidor Web Concorrente 2023-2
Sistemas Operacionais
UFSC
7
Lista 4 - 2023-2
Sistemas Operacionais
UFSC
1
Trabalho Prático 1 Resolvido-2023 1
Sistemas Operacionais
UFSC
16
Slide - Gerência de Memória parte 2 - 2023-2
Sistemas Operacionais
UFSC
10
Lista 3 - 2023-2
Sistemas Operacionais
UFSC
1
Trabalho Prático 2-2023 1
Sistemas Operacionais
UFSC
Preview text
UNIVERSIDADE FEDERAL DE SANTA CATARINA CAMPUS ARARANGUÁ Sistemas Operacionais Prof. Roberto Rodrigues Filho Lista de Exercícios 1 – 2023/2 Esta atividade consiste em responder 6 questões. Faça um arquivo para escrever as respostas das questões. Para cada questão, escreva códigos em Python para demonstrar e embasar sua resposta. No final, transforme o arquivo que contenha as respostas de cada questão em um arquivo PDF e juntamente com os códigos produzidos crie um arquivo .zip com todos os arquivos produzidos. Submeta o arquivo .zip final na atividade do Moodle até o dia 06/10/23. Importante: • Cuidado com plágio nas respostas. • A resolução da lista é individual. • Para submissão, agrupe todos os códigos (os arquivos .py), juntamente com o arquivo PDF com as respostas das questões em um arquivo .zip para enviar no Moodle. 1) Escreva sua versão do bash usando execlp e fork em Python e escreva uma explicação de como o seu programa funciona. 2) Escreva um programa em Python que tenha uma variável global A com qualquer valor. A partir desse processo, crie um processo filho (usando fork). No processo pai, altere o valor da variável A e imprima na tela o valor da variável antes e depois de ela ser alterada. No processo filho, faça a mesma coisa, altere o valor da variável A e imprima o valor antes e depois da variável ser alterada. Descreva o que aconteceu. Qual o valor que a variável assumiu antes e depois no processo pai e no processo filho? Escreva sua explicação do porquê as variáveis assumiram esses valores (use o conceito de isolamento entre os processos). 3) Escreva o mesmo programa da questão anterior (questão 2) usando a biblioteca threading ao invés de usar processos (fork). Explique o que aconteceu com o valor da variável no primeiro thread e no segundo thread antes e depois de alterar o valor da variável. Explique qual a diferença que você notou ao usar threads e processos e explique por que houve essas diferenças. 4) Escreva um programa monothread (ou seja, que possua somente um único thread) que faça a leitura de um arquivo e procura uma determinada palavra em um arquivo texto grande. No final, o programa deve informar o número de vezes que a palavra aparece no documento. Vocês podem criar o arquivo texto usando alguma página de artigo da Wikipedia (https://pt.wikipedia.org/). Explique o funcionamento do seu código. 5) Transforme o programa monothread anterior em um programa multithread. O programa multithread deverá dividir a busca da palavra em diferentes sessões do arquivo para que elas ocorram em diferentes threads (use três threads ou mais). Explique o funcionamento de seu código. 6) Adicione a biblioteca time em seus programas anteriores (questões 4 e 5) e mostre qual código acaba sendo mais rápido, monothread ou multithread? Dê uma explicação do porquê. Questão 1 O programa espera o usuário digitar um comando no terminal e então o comando inserido é dividido em partes para separar o comando principal dos seus argumentos. Usamos os.fork() para criar um processo filho e se fork() retornar 0, significa que estamos no processo filho. No processo filho, o comando é executado usando os.execlp(), que tem como função substituir a imagem do processo atual pelo programa especificado. O processo pai espera o processo filho terminar usando os.waitpid(). O programa continua executando, permitindo que o usuário insira novos comandos, até que digite "exit". Para os casos em que o comando digitado não seja encontrado, uma mensagem de erro é impressa, e o processo filho é terminado com os._exit(1). É importante usar os._exit() aqui para garantir que apenas o processo filho seja encerrado, e não o processo pa No processo pai, após a espera pelo término do processo filho, eu verifico o status de saída. Se o processo filho terminou com um erro (indicado por um status de saída diferente de zero), uma mensagem de erro é impressa. Questão 2 Quando o fork() é chamado, ele cria uma cópia do processo atual. Essa cópia inclui todas as variáveis e o estado do processo. No entanto, depois do fork, os dois processos - pai e filho - são executados independentemente um do outro. No processo pai a variável global A é modificada para 20, portanto o valor de A antes da alteração será 5 e depois da alteração será 20 Já no processo filho, A variável global A é independente da variável A no processo pai e mantém seu valor inicial (5), pois a cópia do processo é uma cópia instantânea do estado no momento do fork. A é então modificada para 10 no processo filho. Dessa forma, o valor de A antes da alteração será 5 e após a alteração será 10. Como cada processo tem seu próprio espaço de endereçamento privado, então a modificação da variável A no processo filho não tem impacto sobre a variável A no processo pai, e vice-versa. Este é um princípio fundamental do isolamento de processos em sistemas operacionais modernos, garantindo a segurança e a estabilidade do sistema. Questão 3: Quando executamos esse programa com threads, observamos que ambos os Threads acessam a mesma variável global A. Como threads compartilham o mesmo espaço de memória, a variável global A é a mesma para ambos. Isso significa que as modificações feitas em A por um thread são visíveis para o outro. A Saída Depende da Ordem de Execução dos Threads. Se o número 1 (que define A como 10) for executado primeiro, A irá mudar de 5 para 10 e depois para 20. Se o número 2 (que define A como 20) for executado primeiro, A mudará de 5 para 20 e depois talvez para 10 dependendo de quando thread número 1 é executado. A principal diferença observada ao usar threads em vez de processos é como eles tratam a variável global A. Em threads, A é compartilhada e sujeita a modificações concorrentes, enquanto em processos, cada processo tem sua própria cópia independente de A. Essa diferença é fundamental e é uma consideração importante ao escolher entre usar threads ou processos em um programa. Questão 4 Temos uma função count_word_in_file que recebe dois parâmetros: o nome do arquivo (filename) e a palavra que está sendo procurada (word). Leitura do Arquivo: O arquivo é aberto em modo de leitura ('r'). O uso de encoding='utf-8' garante que o programa possa ler corretamente arquivos em UTF-8, que é um formato comum para textos. O programa lê o arquivo linha por linha. Para cada linha, ele usa o método count para encontrar quantas vezes a palavra especificada aparece. Ele soma essas contagens para obter o número total de ocorrências da palavra no arquivo. No final, a função retorna o número total de vezes que a palavra aparece no arquivo. Questão 5 O arquivo é dividido em seções iguais (neste caso, três). A função split_file_in_sections calcula os pontos de início e fim de cada seção baseando-se no tamanho total do arquivo. Para cada seção do arquivo, um thread é criado. Cada thread executa a função count_word_in_section, que lê e conta as ocorrências da palavra na sua respectiva seção. Cada thread conta as ocorrências da palavra independente dos outros, apenas na sua seção designada do arquivo. Os resultados de cada thread são armazenados em um dicionário results. Após todos os threads terminarem sua execução, os resultados são agregados para obter a contagem total. O programa imprime então o número total de vezes que a palavra aparece no arquivo, que é a soma das contagens de cada thread. Questão 6 A versão do programa com monothread teve um desempenho melhor do que o multithread. O arquivo é relativamente curto e contém poucas instâncias da palavra 'Lovelace', o que significa que a tarefa de contagem é muito rápida. Como o arquivo é pequeno e a tarefa de contar uma palavra específica é simples, o programa monothread pode processar rapidamente o arquivo inteiro sem o overhead associado à criação e gerenciamento de múltiplos threads. No programa monothread, o arquivo é lido de forma sequencial, o que é geralmente mais eficiente para arquivos menores. Por outro lado, no multithreading, cada thread pode ter que buscar diferentes partes do arquivo, o que pode resultar em uma leitura de arquivo menos eficiente.
Send your question to AI and receive an answer instantly
Recommended for you
8
Lista 2 - 2023-2
Sistemas Operacionais
UFSC
6
Lista - Servidor Web Concorrente 2023-2
Sistemas Operacionais
UFSC
7
Lista 4 - 2023-2
Sistemas Operacionais
UFSC
1
Trabalho Prático 1 Resolvido-2023 1
Sistemas Operacionais
UFSC
16
Slide - Gerência de Memória parte 2 - 2023-2
Sistemas Operacionais
UFSC
10
Lista 3 - 2023-2
Sistemas Operacionais
UFSC
1
Trabalho Prático 2-2023 1
Sistemas Operacionais
UFSC
Preview text
UNIVERSIDADE FEDERAL DE SANTA CATARINA CAMPUS ARARANGUÁ Sistemas Operacionais Prof. Roberto Rodrigues Filho Lista de Exercícios 1 – 2023/2 Esta atividade consiste em responder 6 questões. Faça um arquivo para escrever as respostas das questões. Para cada questão, escreva códigos em Python para demonstrar e embasar sua resposta. No final, transforme o arquivo que contenha as respostas de cada questão em um arquivo PDF e juntamente com os códigos produzidos crie um arquivo .zip com todos os arquivos produzidos. Submeta o arquivo .zip final na atividade do Moodle até o dia 06/10/23. Importante: • Cuidado com plágio nas respostas. • A resolução da lista é individual. • Para submissão, agrupe todos os códigos (os arquivos .py), juntamente com o arquivo PDF com as respostas das questões em um arquivo .zip para enviar no Moodle. 1) Escreva sua versão do bash usando execlp e fork em Python e escreva uma explicação de como o seu programa funciona. 2) Escreva um programa em Python que tenha uma variável global A com qualquer valor. A partir desse processo, crie um processo filho (usando fork). No processo pai, altere o valor da variável A e imprima na tela o valor da variável antes e depois de ela ser alterada. No processo filho, faça a mesma coisa, altere o valor da variável A e imprima o valor antes e depois da variável ser alterada. Descreva o que aconteceu. Qual o valor que a variável assumiu antes e depois no processo pai e no processo filho? Escreva sua explicação do porquê as variáveis assumiram esses valores (use o conceito de isolamento entre os processos). 3) Escreva o mesmo programa da questão anterior (questão 2) usando a biblioteca threading ao invés de usar processos (fork). Explique o que aconteceu com o valor da variável no primeiro thread e no segundo thread antes e depois de alterar o valor da variável. Explique qual a diferença que você notou ao usar threads e processos e explique por que houve essas diferenças. 4) Escreva um programa monothread (ou seja, que possua somente um único thread) que faça a leitura de um arquivo e procura uma determinada palavra em um arquivo texto grande. No final, o programa deve informar o número de vezes que a palavra aparece no documento. Vocês podem criar o arquivo texto usando alguma página de artigo da Wikipedia (https://pt.wikipedia.org/). Explique o funcionamento do seu código. 5) Transforme o programa monothread anterior em um programa multithread. O programa multithread deverá dividir a busca da palavra em diferentes sessões do arquivo para que elas ocorram em diferentes threads (use três threads ou mais). Explique o funcionamento de seu código. 6) Adicione a biblioteca time em seus programas anteriores (questões 4 e 5) e mostre qual código acaba sendo mais rápido, monothread ou multithread? Dê uma explicação do porquê. Questão 1 O programa espera o usuário digitar um comando no terminal e então o comando inserido é dividido em partes para separar o comando principal dos seus argumentos. Usamos os.fork() para criar um processo filho e se fork() retornar 0, significa que estamos no processo filho. No processo filho, o comando é executado usando os.execlp(), que tem como função substituir a imagem do processo atual pelo programa especificado. O processo pai espera o processo filho terminar usando os.waitpid(). O programa continua executando, permitindo que o usuário insira novos comandos, até que digite "exit". Para os casos em que o comando digitado não seja encontrado, uma mensagem de erro é impressa, e o processo filho é terminado com os._exit(1). É importante usar os._exit() aqui para garantir que apenas o processo filho seja encerrado, e não o processo pa No processo pai, após a espera pelo término do processo filho, eu verifico o status de saída. Se o processo filho terminou com um erro (indicado por um status de saída diferente de zero), uma mensagem de erro é impressa. Questão 2 Quando o fork() é chamado, ele cria uma cópia do processo atual. Essa cópia inclui todas as variáveis e o estado do processo. No entanto, depois do fork, os dois processos - pai e filho - são executados independentemente um do outro. No processo pai a variável global A é modificada para 20, portanto o valor de A antes da alteração será 5 e depois da alteração será 20 Já no processo filho, A variável global A é independente da variável A no processo pai e mantém seu valor inicial (5), pois a cópia do processo é uma cópia instantânea do estado no momento do fork. A é então modificada para 10 no processo filho. Dessa forma, o valor de A antes da alteração será 5 e após a alteração será 10. Como cada processo tem seu próprio espaço de endereçamento privado, então a modificação da variável A no processo filho não tem impacto sobre a variável A no processo pai, e vice-versa. Este é um princípio fundamental do isolamento de processos em sistemas operacionais modernos, garantindo a segurança e a estabilidade do sistema. Questão 3: Quando executamos esse programa com threads, observamos que ambos os Threads acessam a mesma variável global A. Como threads compartilham o mesmo espaço de memória, a variável global A é a mesma para ambos. Isso significa que as modificações feitas em A por um thread são visíveis para o outro. A Saída Depende da Ordem de Execução dos Threads. Se o número 1 (que define A como 10) for executado primeiro, A irá mudar de 5 para 10 e depois para 20. Se o número 2 (que define A como 20) for executado primeiro, A mudará de 5 para 20 e depois talvez para 10 dependendo de quando thread número 1 é executado. A principal diferença observada ao usar threads em vez de processos é como eles tratam a variável global A. Em threads, A é compartilhada e sujeita a modificações concorrentes, enquanto em processos, cada processo tem sua própria cópia independente de A. Essa diferença é fundamental e é uma consideração importante ao escolher entre usar threads ou processos em um programa. Questão 4 Temos uma função count_word_in_file que recebe dois parâmetros: o nome do arquivo (filename) e a palavra que está sendo procurada (word). Leitura do Arquivo: O arquivo é aberto em modo de leitura ('r'). O uso de encoding='utf-8' garante que o programa possa ler corretamente arquivos em UTF-8, que é um formato comum para textos. O programa lê o arquivo linha por linha. Para cada linha, ele usa o método count para encontrar quantas vezes a palavra especificada aparece. Ele soma essas contagens para obter o número total de ocorrências da palavra no arquivo. No final, a função retorna o número total de vezes que a palavra aparece no arquivo. Questão 5 O arquivo é dividido em seções iguais (neste caso, três). A função split_file_in_sections calcula os pontos de início e fim de cada seção baseando-se no tamanho total do arquivo. Para cada seção do arquivo, um thread é criado. Cada thread executa a função count_word_in_section, que lê e conta as ocorrências da palavra na sua respectiva seção. Cada thread conta as ocorrências da palavra independente dos outros, apenas na sua seção designada do arquivo. Os resultados de cada thread são armazenados em um dicionário results. Após todos os threads terminarem sua execução, os resultados são agregados para obter a contagem total. O programa imprime então o número total de vezes que a palavra aparece no arquivo, que é a soma das contagens de cada thread. Questão 6 A versão do programa com monothread teve um desempenho melhor do que o multithread. O arquivo é relativamente curto e contém poucas instâncias da palavra 'Lovelace', o que significa que a tarefa de contagem é muito rápida. Como o arquivo é pequeno e a tarefa de contar uma palavra específica é simples, o programa monothread pode processar rapidamente o arquivo inteiro sem o overhead associado à criação e gerenciamento de múltiplos threads. No programa monothread, o arquivo é lido de forma sequencial, o que é geralmente mais eficiente para arquivos menores. Por outro lado, no multithreading, cada thread pode ter que buscar diferentes partes do arquivo, o que pode resultar em uma leitura de arquivo menos eficiente.