1. Sim, a limitação de threads no software poderia ocorrer tendo em vista as limitações
do hardware utilizado, bem como o gargalo atingido devido a criação de inúmeras threads com base em pedidos dos clientes, contudo, o número de threads definidas pode não ser capaz de atender aos clientes com eficiência, tornando o sistema ineficaz. 2. As operações de thread com maior custo são a criação e destruição das threads, onde apesar de ser uma ação menos custosa que criar e destruir processos, ainda é oneroso para o sistema quando é feita em grande número ou frequentemente, e também os chaveamentos realizados entre as thread de E/S e as threads trabalhadoras, onde a manipulação das filas pode se tornar custoso. 3. A arquitetura de threads trabalhadoras é a forma básica para inicializar um servidor, onde é definido um número fixo de threads trabalhadoras para atender às solicitações, como vantagem, pode-se citar a possibilidade de criação de filas de prioridade para o atendimento de solicitações mais urgentes, já como desvantagem é possível citar o número fixo de threads definido, o qual pode não atender a demanda dos clientes dependendo do número de pedidos, e ainda o custo causado pelo gerenciamento das filas por meio da thread de E/S. Já a arquitetura de threads por pedido cria uma nova thread a cada solicitação realizada, a qual se autodestrói ao término da tarefa, como vantagem, há a criação de quantas threads forem necessárias para o atendimento do pedidos realizados, sem a existência da fila presente na arquitetura anterior, já como desvantagem, é possível citar o custo da criação e destruição de inúmeras threads, onde um só cliente pode gerar diversos pedidos, e a cada vez uma nova thread é criada. 4. A associação de uma thread dedicada a um processo leve do cliente é ineficiente, haja vista que o processo não realiza muitas requisições à thread, levando a uma subutilização de um recurso que poderia ser alocado a outro processo cliente, o qual pode estar com mais requisições pendentes ou necessitar de maior poder de processamento. 5. A utilização de um núcleo monolítico concentra as operações no núcleo, onde tem como vantagem a eficiência na invocação de tais operações em relação a operação realizada em nível de usuário, como desvantagem se tem o código não modular, o qual é difícil de manter e alterar. Já o micronúcleo oferece apenas os elementos mais básicos como threads e espaço de endereçamento, deixando as demais operações a cargo de servidores carregados diretamente nas máquinas solicitantes, como vantagem cita-se sua extensibilidade e também modularidade que é obtida por meio da imposição de limites na memória, já a desvantagem está na necessidade carregar as demais operações na máquina solicitante através de requisição por mensagem. 6. O processo lê os dados gravados pelo núcleo na região compartilhada, não sendo necessária a cópia dos dados no espaço de endereçamento do núcleo, o que torna a região compartilhada mais eficiente. É possível que interrupções sejam realizadas a fim de sincronizar os dados escritos por parte do usuário e núcleo. 7. Em nível de usuário, no caso onde o núcleo não reconhece múltiplas threads, não é possível realizar o escalonamento individual a nível de núcleo, visto que o núcleo enxerga o processo como uma única thread, o escalonamento de múltiplas threads é realizado em nível de usuário por bibliotecas ligadas as aplicações, as quais reconhecem as múltiplas threads e as tratam. No caso de chamada de sistema em um ambiente bloqueante, a thread bloqueia a si e as demais, uma vez que o núcleo só enxerga uma thread. 8. A interrupção realizada por dispositivos externos pode ser comunicada por meio das bibliotecas associadas às aplicações em nível de usuário, onde outras operações como preempção e bloqueio são comunicadas através da ativação do escalonador pelo próprio núcleo. 9. 9.1. Cliente: Argumentos: 5ms
Send/receive: O cliente irá realizar um envio e receber uma resposta por
requisição => 0,5 ms x 2 = 1
Empacotamento/ Desempacotamento: O cliente irá realizar o
empacotamento e desempacotamento => 0,5 ms x 2 = 1
Total no cliente: 5 + 1 + 1 = 7 ms
Total no servidor: 10 ms
Transporte: Realizar o transporte de uma solicitação e uma resposta => 3 ms x 2
= 6 ms
Total por requisição: 7 + 10 + 6 = 23 ms
Como são realizadas duas requisições: 23 x 2 = 46 ms
9.2. Para duas threads:
10 + 6 = 16 ms * 2 requisições = 32ms + 7 ms (cliente possui duas threads) =>