Как отмечается в комментариях, ваша основная программа должна ждать окончания работы детей, и вам нужно использовать j
в dormir()
.
Если вы спите 4, 8, больше секунд ввремя, это займет много времени (10+ минут), чтобы завершить.Измените вызовы сна на sleep10(int n)
, чтобы спать n
десятых долей секунды, и, обеспечив реализацию с использованием nanosleep()
, код завершается примерно за 75 секунд.
Вам также необходимо убедиться, чтоодин принимает 2 таблетки, когда остается только одна таблетка;получение отрицательного 'medicamentos sobrando' оставляет программу запущенной на неопределенный срок.
В Linux void main()
безусловно неверен;используйте int main(void)
и (предпочтительно) явный return 0;
в конце main()
, если у вас нет альтернативного статуса для возврата.
Код также выводит номера PID перед сообщениями, чтобы определить, какой процесс выполняеткакие.Есть место, чтобы думать, что должно быть напечатано больше информации, но моего испанского достаточно не существует, поэтому я не собираюсь пытаться это делать.Программа main()
сообщает о детях и их статусах выхода при выходе.
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
#include <time.h>
#define ACORDADO 0
#define ESPERANDO 1
#define DORMINDO 2
#define N 7
void mostrar(void);
void dormir(int);
void tomar_med(int);
void esperar(int);
void acordar(int);
void liberar_cama(int);
void acao_idoso(int j);
void forker(int n_proc);
int medicamentos = 90;
int camas = 5;
int idosos[N];
int main(void)
{
forker(N);
int corpse;
int status;
while ((corpse = wait(&status)) > 0)
printf("PID %5d exited with status 0x%.4X\n", corpse, status);
return 0;
}
static void sleep10(int n)
{
assert(n > 0 && n < 100);
struct timespec ts = { .tv_sec = n / 10, .tv_nsec = (n % 10) * 100000000 };
printf("%d: sleeping %d.%ds\n", (int)getpid(), n / 10, n % 10);
nanosleep(&ts, 0);
}
void forker(int n_proc)
{
pid_t pid;
if (n_proc > 0)
{
if ((pid = fork()) < 0)
{
perror("fork");
}
else if (pid == 0)
{
printf("%d: PID %d\n", n_proc, (int)getpid());
acao_idoso(n_proc - 1);
}
else if (pid > 0)
{
mostrar();
forker(n_proc - 1);
}
}
}
void mostrar()
{
int pid = getpid();
for (int i = 0; i < N; i++)
{
if (idosos[i] == ACORDADO)
printf("%d: O idoso %d esta acordado.\n", pid, i + 1);
if (idosos[i] == ESPERANDO)
printf("%d: O idoso %d esta esperando.\n", pid, i + 1);
if (idosos[i] == DORMINDO)
printf("%d: O idoso %d esta dormindo.\n", pid, i + 1);
}
printf("\n");
printf("%d: %d medicamentos sobrando.\n", pid, medicamentos);
printf("\n");
}
void acao_idoso(int j)
{
int i = j;
while (medicamentos != 0)
{
acordar(i);
mostrar();
esperar(i);
mostrar();
dormir(i);
mostrar();
liberar_cama(i);
mostrar();
}
}
void acordar(int i)
{
if (idosos[i] == ACORDADO)
{
int t = rand() % 11;
sleep10(t + 1);
}
}
void esperar(int i)
{
if (idosos[i] == ACORDADO && medicamentos > 0)
idosos[i] = ESPERANDO;
}
static inline int min(int x, int y) { return (x < y) ? x : y; }
void dormir(int i)
{
if ((idosos[i] == ESPERANDO) && (camas >= 1))
{
int j = rand();
if (j % 2 == 0)
{
medicamentos = medicamentos - min(2, medicamentos);
sleep10(8);
}
else
{
medicamentos = medicamentos - 1;
sleep10(4);
}
camas = camas - 1;
idosos[i] = DORMINDO;
}
}
void liberar_cama(int i)
{
if (idosos[i] == DORMINDO)
{
idosos[i] = ACORDADO;
camas++;
}
}