Questão nº 36
Questão de Tecnologia da Informação · FCC TRT-12 2023 (nº 36)
Examine o programa em C abaixo.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define NUM_ADVOGADOS 3
void advogado(int id) {
printf("Advogado %d: Preparando argumentos\n", id);
usleep(rand() % 2000000 + 1000000); // Simula o tempo de preparação
printf("Advogado %d: Apresentando o caso ao tribunal\n", id);
usleep(rand() % 2000000 + 1000000); // Simula o tempo de apresentação
printf("Advogado %d: Caso resolvido\n", id);
}
int main() {
srand(time(NULL));
for (int i = 1; i <= NUM_ADVOGADOS; i++) {
if (fork() == 0) {
I
......
}
}
// Código do processo pai (tribunal)
for (int i = 1; i <= NUM_ADVOGADOS; i++) {
wait(NULL); // aguarda todos os processos filhos terminarem
}
printf("Todos os casos foram resolvidos.\n");
return 0;
}
Considerando que uma das saídas do programa acima, compilado e executado em condições ideais, seja:
Advogado 1: Preparando argumentos
Advogado 3: Preparando argumentos
Advogado 2: Preparando argumentos
Advogado 3: Apresentando o caso ao tribunal
Advogado 2: Apresentando o caso ao tribunal
Advogado 1: Apresentando o caso ao tribunal
Advogado 1: Caso resolvido
Advogado 3: Caso resolvido
Advogado 2: Caso resolvido
Todos os casos foram resolvidos.
A lacuna I deve ser corretamente preenchida com:
- A`advogado(i+1); break(1);`
- B`advogado((fork(i))); exit(1);`
- C`advogado(i);`
- D`advogado(i); exit(0);` (alternativa correta)
- E`advogado(i+1);`
Resposta comentada
Gabarito Alternativa D
Ao lidar com processos (programas em execução independentes) criados com fork(), é crucial entender que cada processo filho recebe uma cópia do código do pai. O fork() retorna um valor diferente para o pai e para o filho, permitindo que eles executem caminhos distintos.
- (A) Incorreta:
break(1)não é uma função válida em C para sair de um loop ou programa. A intenção de sair do loopforapós o primeiro filho ser criado é compreensível, mas a sintaxe está errada. - (D) Correta: O
fork()retorna 0 para o processo filho. Dentro desseif (fork() == 0), o código do filho é executado. A funçãoadvogado(i)chama a função que simula o trabalho do advogado, passando o ID do loop atual. Oexit(0)é essencial para que o processo filho termine sua execução após completar sua tarefa, liberando recursos e sinalizando ao processo pai que ele concluiu. Sem oexit(0), o processo filho continuaria executando o código do loopfordo pai, o que não é o comportamento desejado para um processo filho. A armadilha aqui é esquecer que o filho precisa terminar sua execução após fazer o que foi designado, e oexit(0)cumpre exatamente essa função. - (B) Incorreta:
fork(i)não é uma chamada válida parafork(). A funçãofork()não recebe argumentos.exit(1)indica um erro na saída, o que não é o caso aqui, pois o filho está executando sua tarefa normalmente. - (C) Incorreta: Se apenas
advogado(i);for usado, o processo filho executará a funçãoadvogadoe, em seguida, continuará executando o restante do loopfordo pai. Isso faria com que múltiplos processos filhos fossem criados em cascata, e o código do pai seria executado por todos os filhos após a criação. - (E) Incorreta: Similar à alternativa C, se apenas
advogado(i+1);for usado, o processo filho executará a funçãoadvogadoe depois continuará no loop do pai. Além disso, a passagem dei+1paraadvogadonão se alinha com a numeração dos advogados (1 a 3) que começa comi=1.
Fonte: FCC TRT-12 2023 Analista Judiciário - Área Apoio Especializado - Especialidade Tecnologia da Informação (Caderno Tipo 003). Reproduzida para fins de estudo.