C - Несколько дочерних вилок с петлями - PullRequest
0 голосов
/ 12 мая 2018

Итак, мне нужно создать 7 дочерних процессов с помощью fork, и каждый из них должен работать в цикле, пока не закончатся медикаменты (лекарства).Но они запускаются только по одному, а иногда только один раз.Переменные и другие имена находятся в pt-br, но я поставлю переводы.Таким образом, это должен был быть дом престарелых (ужасный, хотя хе-хе-хе), и у него ограниченное количество лекарств.Человеку нужна 1 таблетка, чтобы спать 4 часа, а 8 - 8 часов.Кроме того, есть только 5 спальных мест, в результате чего получается «линия ожидания» для спальных мест.Как только есть свободная кровать, старейшина, который не спит и ждет кровати, возьмет 1 или 2 таблетки наугад и уснет.После этого он уйдет с кровати, дав другому человеку спать.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#define ACORDADO 0 //awake
#define ESPERANDO 1 //waiting
#define DORMINDO 2 //sleeping
#define N 7

void mostrar(void); //show info
void dormir(int); //sleep
void tomar_med(int); //take meds
void esperar(int);//wait
void acordar(int);//wake up
void liberar_cama(int);//leave the bed
void acao_idoso(int j);//elder action

int medicamentos = 90; //meds
int camas = 5; //beds
int idosos [N]; //elders
int i;

void forker(int n_proc)
{
    pid_t pid;

    if(n_proc > 0)
    {
        if ((pid = fork()) < 0){
            perror("fork");

        }else if (pid == 0){ //filho
            acao_idoso(n_proc - 1);

        }else if(pid > 0){ //pai
            mostrar();
            forker(n_proc - 1);
        }
    }
}

void main(){


    forker(7);

}

void mostrar(){
    for(i=0;i<N;i++){
        if(idosos[i] == ACORDADO)
            printf("O idoso %d esta acordado.\n", i+1); //elder is awake
        if(idosos[i] == ESPERANDO)
            printf("O idoso %d esta esperando.\n", i+1); //elder is waiting
        if(idosos[i] == DORMINDO)
            printf("O idoso %d esta dormindo.\n", i+1); //elder is asleep
    }
    printf("\n");   
    printf("%d medicamentos sobrando.\n", medicamentos); //%d meds left
    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;
        sleep(t+1);
    }
}

void esperar(int i){
    if(idosos[i] == ACORDADO && medicamentos > 0)
        idosos[i] = ESPERANDO;
}

void dormir(int i){
    if((idosos[i] == ESPERANDO) && (camas >= 1)){
        int j = rand();

        if(i % 2 == 0){
            medicamentos = medicamentos - 2;
            sleep(8);
        }else{
            medicamentos = medicamentos - 1;
            sleep(4);
        }

        camas = camas - 1;
        idosos[i] = DORMINDO;

    }
}

void liberar_cama(int i){
    if(idosos[i] == DORMINDO){
        idosos[i] = ACORDADO;
        camas++;
    }
}

1 Ответ

0 голосов
/ 12 мая 2018

Как отмечается в комментариях, ваша основная программа должна ждать окончания работы детей, и вам нужно использовать 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++;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...