执行另一个程序+儿童死亡

时间:2013-10-08 00:28:19

标签: c linux unix fork

我正在尝试编写一个程序,根据用户输入值'n',我将分叉许多进程同时运行 。此外,每个孩子都试图执行我创建的另一个文件,这将生成x睡眠时间和x退出值。最终,当孩子死亡时,父母需要打印pid和exit_status。重要的是确保儿童死亡是x,而不是并发。到目前为止,有两件事我无法弄清楚。

  1. 让我的execl运行我的sleep.c文件(如下所示)。
  2. 让孩子们随意地分叉和死亡,而不是有秩序地死亡,结果印刷者死亡,并产生随机退出状态。
  3. 我有两个文件,Sleep.c和Ranchild.c。

    SLEEP.C

    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <time.h>
    
    /* Generated random sleep time, and return random exit value */
    
    int main()
    {
        /* Calculate A Random Time To Sleep 1 - 10 Seconds*/
        srand(time(NULL));
        int r = (rand() % 10) + 1;
    
        printf("Sleep Time: %d\n", r);
        sleep(r);
    
        /* Calculate A Random Exit Value */
        int r2 = (rand() % 30) + 1;
        exit(r2);       
    }
    

    #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <time.h> /* Generated random sleep time, and return random exit value */ int main() { /* Calculate A Random Time To Sleep 1 - 10 Seconds*/ srand(time(NULL)); int r = (rand() % 10) + 1; printf("Sleep Time: %d\n", r); sleep(r); /* Calculate A Random Exit Value */ int r2 = (rand() % 30) + 1; exit(r2); }

    RANCHILD.C

    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <time.h>
    
    int main()
    {
        /* Get User Input */
        int i, n;
    
        printf("Please Enter An Integer!\n");
    
        /* Test User Input */
        if(!scanf("%d", &n)) {
            printf("Invalid Input!\n");
            return -1;
        }   
    
        /* Initialize Needed Variables */
        pid_t pid[n];
        int status, exit_status;
    
        for(i = 0; i < n; i++) {
    
            if((pid[i] = fork()) < 0) {
                perror("Fork Failed!");
                return -2;
            }
    
            if(pid[i] == 0) {
                execl("sleep", "sleep", (char *)0);
    } else {
        /* Print Child Results */
        if (waitpid(-1, &status, WNOHANG) == 0) {
            if(WIFEXITED(status)) {
                exit_status = WEXITSTATUS(status);
                printf("Exit Status From %d was %d!\n", pid[i], exit_status);
            }
        }   
    
    }       
        }
    
        exit(0);
    }
    

    它永远不会设法执行Sleep文件,结果的样本如下: #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <time.h> int main() { /* Get User Input */ int i, n; printf("Please Enter An Integer!\n"); /* Test User Input */ if(!scanf("%d", &n)) { printf("Invalid Input!\n"); return -1; } /* Initialize Needed Variables */ pid_t pid[n]; int status, exit_status; for(i = 0; i < n; i++) { if((pid[i] = fork()) < 0) { perror("Fork Failed!"); return -2; } if(pid[i] == 0) { execl("sleep", "sleep", (char *)0); } else { /* Print Child Results */ if (waitpid(-1, &status, WNOHANG) == 0) { if(WIFEXITED(status)) { exit_status = WEXITSTATUS(status); printf("Exit Status From %d was %d!\n", pid[i], exit_status); } } } } exit(0); }

    非常感谢您的帮助!!

2 个答案:

答案 0 :(得分:2)

建议这样的事情。乔纳森是对的。你需要更好的种子rand。孩子们跑的速度很快,他们很可能会以相同的睡眠时间和退出代码结束。

int ret;

for (i = 0; i < n; i++)
{

    if ((pid[i] = fork()) < 0)
    {
        perror("Fork Failed!");
        return -2;
    }

    if (pid[i] == 0)
    {
        if ((ret = execl("sleep", "sleep", (char *)0)) == -1)
        {
            perror("execl");
            exit(1);
        }
    }
}

for (i = 0; i < n; i++)
{
   if (wait(&status) == -1)
   {
      perror("wait"); exit(1);
   }

   if (WIFEXITED(status))
   {
       exit_status = WEXITSTATUS(status);
       printf("Exit Status From %d was %d!\n", pid[i], exit_status);
   }
}

child / execl程序

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <math.h>

/* Generated random sleep time, and return random exit value */

void getRandomNumbers(int *r1, int *r2)
{
    int fd;

    if (((fd = open("/dev/urandom", O_RDONLY))) == -1)
    { perror("open"); exit(1);}

    read(fd, r1, sizeof(int));
    read(fd, r2, sizeof(int));
    close(fd);

    return;
}

int main()
{
    int r1 = 0, r2 = 0;

    getRandomNumbers(&r1, &r2);

    int sleeptime = abs((r1 % 10)) + 1;

    printf("Sleep Time: %d\n", sleeptime);
    sleep(sleeptime);

    int exitcode = abs((r2 % 30)) + 1;

    exit(exitcode);
}

答案 1 :(得分:1)

sleep.c

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

/* Generated random sleep time, and return random exit value */
int main(int argc, char **argv)
{
    int seed = time(0);
    if (argc > 1)
        seed = atoi(argv[1]);
    srand(seed);

    int r = (rand() % 10) + 1;
    int r2 = (rand() % 30) + 1;

    printf("%d: Seed: %d; Sleep: %d; Exit %d\n", (int)getpid(), seed, r, r2);

    sleep(r);
    exit(r2);       
}

ranchild.c

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <time.h>

int main(int argc, char **argv)
{
    int n = 10;
    if (argc > 1)
        n = atoi(argv[1]);
    if (n <= 0)
    {
        fprintf(stderr, "%s: invalid number of processes %d\n", argv[0], n);
        return(1);
    }

    int i;
    pid_t pid[n];
    int t = time(0);
    srand(t);

    printf("Time/seed: %d\n", t);

    for (i = 0; i < n; i++)
    {
        int seed = rand();
        fflush(0);
        if ((pid[i] = fork()) < 0)
        {
            fprintf(stderr, "%s: Fork Failed!\n", argv[0]);
            return -2;
        }
        if (pid[i] == 0)
        {
            const char command[] = "sleep";
            char argument[15];
            snprintf(argument, sizeof(argument), "%d", seed);
            execl(command, command, argument, (char *)0);
            fprintf(stderr, "%d: failed to execute %s\n", (int)getpid(), command);
            return(1);
        }
        printf("Child: %d (%d)\n", pid[i], seed);
    }

    int corpse, status;
    while ((corpse = waitpid(-1, &status, 0)) > 0)
    {
        if (WIFEXITED(status))
            printf("%d: Exit Status From %d was %d!\n",
                   (int)time(0), corpse, WEXITSTATUS(status));
        else
            printf("%d: Exit status from %d was 0x%.4X\n",
                   (int)time(0), corpse, status);
    }

    return(0);
}

示例输出

Time/seed: 1381199552
Child: 66443 (1670130041)
Child: 66444 (116849150)
Child: 66445 (1083610692)
Child: 66446 (1583573884)
Child: 66447 (1361431117)
Child: 66448 (134524634)
Child: 66449 (1802726994)
Child: 66450 (1733296282)
Child: 66451 (894940019)
66443: Seed: 1670130041; Sleep: 1; Exit 13
66452: Seed: 281435745; Sleep: 2; Exit 11
66444: Seed: 116849150; Sleep: 3; Exit 5
66449: Seed: 1802726994; Sleep: 3; Exit 30
66447: Seed: 1361431117; Sleep: 5; Exit 25
66445: Seed: 1083610692; Sleep: 5; Exit 8
66448: Seed: 134524634; Sleep: 5; Exit 23
66451: Seed: 894940019; Sleep: 6; Exit 22
66446: Seed: 1583573884; Sleep: 8; Exit 15
66450: Seed: 1733296282; Sleep: 10; Exit 16
Child: 66452 (281435745)
1381199553: Exit Status From 66443 was 13!
1381199554: Exit Status From 66452 was 11!
1381199555: Exit Status From 66444 was 5!
1381199555: Exit Status From 66449 was 30!
1381199557: Exit Status From 66447 was 25!
1381199557: Exit Status From 66445 was 8!
1381199557: Exit Status From 66448 was 23!
1381199558: Exit Status From 66451 was 22!
1381199560: Exit Status From 66446 was 15!
1381199562: Exit Status From 66450 was 16!