简体   繁体   English

C-带循环的多个子叉

[英]C - Multiple child fork with loops

So I have to create 7 child processes with fork, and each one has to work in loop until medicamentos (meds) runs out. 因此,我必须使用fork创建7个子进程,并且每个子进程都必须循环工作,直到medicamentos(meds)用完为止。 But they only run one at a time, and sometimes only once. 但是它们一次只能运行一次,有时只能运行一次。 The variables and other names are in pt-br, but I'll put translations. 变量和其他名称在pt-br中,但我将进行翻译。 So, it was supposed to be an nursing home (a terrible one tho heheheh) and it has a limited amount of meds. 因此,它本来应该是疗养院(糟糕透顶),而且药物数量有限。 A person needs 1 pill to sleep for 4 hours and 8 for 8 hours. 一个人需要服用1粒药才能睡4个小时,需要8粒才能睡8个小时。 Also, there's only 5 beds, resulting on a "waiting line" for the beds. 此外,只有5张床,因此需要等待这些床。 Once there's a free bed, an elder that's awake and waiting for a bed will take 1 or 2 pills, at random and sleep. 一旦有一张免费的床,一个醒着的等待长者的长者会随机服用1或2片药,然后入睡。 After that, he'll leave the bed, letting another elder sleep. 在那之后,他将离开床,让另一个老人入睡。

#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++;
    }
}

As noted in the comments, your main program needs to wait for the children to finish, and you need to use j in dormir() . 如注释中所述,您的主程序需要等待子dormir()完成,并且需要在dormir()使用j

If you sleep 4, 8, more seconds at a time, it will take a long time (10+ minutes) to complete. 如果您一次睡了4、8秒,则需要较长时间(10分钟以上)才能完成。 Change the sleep calls to sleep10(int n) to sleep n tenths of a second, and providing the implementation using nanosleep() , the code completes in something like 75 seconds. 改变睡眠时调用sleep10(int n)睡眠n十分之一秒,并提供实施使用nanosleep()在东西好像75秒代码完成。

You also need to ensure that no-one takes 2 pills when there's only one pill left; 您还需要确保仅剩一粒药时,没有人可以服用2粒。 getting a negative 'medicamentos sobrando' leaves the program running indefinitely. 获得负面的“ sobrando sobrando”使程序无限期地运行。

On Linux, void main() is unconditionally wrong; 在Linux上, void main()是无条件错误的。 use int main(void) and (preferably) an explicit return 0; 使用int main(void)和(最好)使用显式return 0; at the end of main() unless you have an alternative status to return. main()的末尾,除非您有其他返回状态。

The code also prints out PID numbers before messages to identify which process is doing what. 该代码还会在消息之前打印出PID号,以标识哪个进程在做什么。 There is room to think that there should be more information printed, but my Spanish is sufficiently non-existent that I'm not going to attempt it. 有空间认为应该打印更多的信息,但是我的西班牙语已经不存在了,所以我不会尝试。 The main() program reports on the children and their exit statuses as they exit. 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++;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM