首页 > 其他分享 >操作系统导论习题解答(5. Process API)

操作系统导论习题解答(5. Process API)

时间:2022-10-14 19:15:57浏览次数:74  
标签:fork Process printf pid int API rc 习题 include

0. installing and using of Cygmin

Since Cygwin was installed at the request of the teacher when taking the basic computer class, I will not introduce it here.

1. The fork() System Call

// p1.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    printf("hello world (pid:%d)\n", (int) getpid());
    int rc = fork();
    if (rc < 0) {
    // fork failed
        fprintf(stderr, "fork failed\n");
        exit(1);
    } else if (rc == 0) {
    // child (new process)
        printf("hello, I am child (pid:%d)\n", (int) getpid());
    } else {
        printf("hello, I am parent of %d (pid:%d)\n",
            rc, (int) getpid());
    }
    return 0;
}

在这里插入图片描述
The PID is different each time, which is normal.

2. The wait() System Call

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

int main(int argc, char *argv[])
{
    printf("hello world (pid:%d)\n", (int) getpid());
    int rc = fork();
    if (rc < 0)
    // fork failed; exit
    {
        fprintf(stderr, "fork falied\n");
        exit(1);
    }
    else if (rc == 0)
    // child (new process)
    {
        printf("hello, I am child (pid:%d)\n", (int) getpid());
    }
    else 
    // parent goes down this path (main)
    {
        int rc_wait = wait(NULL);
        printf("hello, I am parent of %d (rc_wait:%d) (pid:%dn",
            rc, rc_wait, (int) getpid());
    }
    return 0;
}

在这里插入图片描述
The child will always print first.

3. The exec() System Call

// p3.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>

int main(int argc, char *argv[]) {
    printf("hello world (pid:%d)\n", (int) getpid());
    int rc = fork();
    if (rc < 0) { // fork failed; exit
        fprintf(stderr, "fork failed\n");
        exit(1);
    } else if (rc == 0) { // child (new process)
        printf("hello, I am child (pid:%d)\n", (int) getpid());
        char *myargs[3];
        myargs[0] = strdup("wc"); // program: "wc" (word count)
        myargs[1] = strdup("p3.c"); // argument: file to count
        myargs[2] = NULL; // marks end of array
        execvp(myargs[0], myargs); // runs word count
        printf("this shouldn’t print out");
    } else { // parent goes down this path (main)
        int rc_wait = wait(NULL);
        printf("hello, I am parent of %d (rc_wait:%d) (pid:%d)\n",
        rc, rc_wait, (int) getpid());
    }
    return 0;
}

在这里插入图片描述
The exec system call does not create a new process, but replaces the content of the original process context. The code segment, data segment, and stack segment of the original process are replaced by the new process.

4. Why? Motivating The API

// p4.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<fcntl.h>
#include<sys/wait.h>

int main(int argc, char *argv[])
{
    int rc = fork();
    if (rc < 0)
    {
        // fork failed
        fprintf(stderr, "fork failed\n");
        exit(1);
    }
    else if (rc == 0)
    {
        // child: redirect standard output to a file
        close(STDERR_FILENO);
        open("./p4.output", O_CREAT | O_WRONLY | O_TRUNC, S_IRWXU);

        // now exec "wc"...
        char *myargs[3];
        myargs[0] = strdup("wc");   // program: wc (word count)
        myargs[1] = strdup("p4.c"); // arg: file to count
        myargs[2] = NULL;           // mark end of array
        execvp(myargs[0], myargs);  // runs word count
    }
    else
    {
        // parent goes down this path (main)
        int rc_wait = wait(NULL);
    }
    return 0;
}

在这里插入图片描述

5. Process Control And Users

在这里插入图片描述

6. Homework(Simulation)

This simulation homework focuses on fork.py, a simple process creation simulator that shows how processes are related in a single “familial” tree. Read the relevant README for details about how to run the simulator.

Question & Answer

1

在这里插入图片描述
test: python forl.py -s 10
python fork.py -s 10
verification: python fork.py -s 10 -c
在这里插入图片描述

2

在这里插入图片描述
test: python fork.py -a 100 -f 0.1
0.1
verification: python fork.py -a 100 -f 0.1 -c
在这里插入图片描述

3

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
You can flip the question around with the -t flag, which allows you to view process tree states and then guess what action must have taken place.

4

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
You can use different random seeds (-s flag) or just don't specify one to get different randomly generated sequences.

6

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
You can try more.

7. Homework (Code)

在这里插入图片描述

Question & Answer

1

在这里插入图片描述

// p1.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>

int main(int argc, char *argv[])
{
    int x = 100;
    printf("hello world (pid:%d), x = %d\n", (int) getpid(), x);
    int rc = fork();
    if (rc < 0)
    {
        // fork failed
        fprintf(stderr, "fork failed\n");
        exit(1);
    }
    else if (rc == 0)
    {
        // child (new process)
        printf("hello, I am child (pid:%d), x = %d\n", (int) getpid(), x);
    }
    else
    {
        // parent goes down this path (main)
        printf("hello, I am parent of %d (pid:%d), x = %d\n",
            rc, (int) getpid(), x);
    }
    return 0;
}

在这里插入图片描述

2

在这里插入图片描述

// p2.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/wait.h>
#include<assert.h>

int main(int argc, char *argv[])
{
    printf("hello world (pid:%d)\n", (int) getpid());

    // open a file
    int fd = open("./openFile", O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
    assert(fd > -1);  // open failed, exit

    int rc = fork();
    if (rc < 0)
    {
        // fork failed
        fprintf(stderr, "fork failed\n");
        exit(1);
    }
    else if (rc == 0)
    {
        // child: redirect standard outpupt to a file
        printf("hello, I am child (pid:%d)\n", (int) getpid());
        printf("fd = %d\n", fd);
    }
    else
    {
        // parent goes down this path (main)
        printf("hello, I am parent of %d (pid:%d)\n", rc, (int) getpid());
        printf("fd = %d\n", fd);
    }
    return 0;
}

在这里插入图片描述

3

在这里插入图片描述

// p3.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>

int main(int argc, char *argv[])
{
    printf("hello world (pid:%d)\n", (int) getpid());
    int rc = fork();
    if (rc < 0)
    {
        // fork failed
        fprintf(stderr, "fork failed\n");
        exit(1);
    }
    else if (rc == 0)
    {
        // child (new process)
        printf("hello, I am child (pid:%d)\n", (int) getpid());
    }
    else
    {
        // parent goes down this path (main)
        int rd = fork();
        if (rd == 0)
            printf("goodbye, I am parent (pid:%d)\n", (int) getpid());
    }
    return 0;
}

在这里插入图片描述

4

在这里插入图片描述

// p4.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/wait.h>

int main(int argc, char *argv[])
{
    printf("hello world (pid:%d)\n", (int) getpid());
    int rc = fork();
    if (rc < 0)
    {
        // fork failed; exit
        fprintf(stderr, "fork failed\n");
        exit(1);
    }
    else if (rc == 0)
    {
        // child (new process)
        printf("hello, I am child (pid:%d)\n", (int) getpid());
        char *myargs[2];
        myargs[0] = strdup("/bin/ls");
        myargs[1] = NULL;
        execvp(myargs[0], myargs);
        printf("this shouldn't print out");
    }
    else
    {
        // parent goes down this path (main)
        int rc_wait = wait(NULL);
        printf("hello, I am parent of %d (rc_wait:%d) (pid:%d)\n", 
           rc, rc_wait, (int) getpid());
    }
    return 0;
}

在这里插入图片描述

5

在这里插入图片描述

// p5a.c wait() in the parent
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/wait.h>

int main(int argc, char *argv[])
{
    printf("hello world (pid:%d)\n", (int) getpid());
    int rc = fork();
    if (rc < 0)
    {
        // fork failed; exit
        fprintf(stderr, "fork failed\n");
        exit(1);
    }
    else if (rc == 0)
    {
        // child (new process)
        printf("hello, I am child (pid:%d)\n", (int) getpid());
    }
    else
    {
        // parent goes down this path (main)
        int rc_wait = wait(NULL);
        printf("hello, I am parent of %d (rc_wait:%d) (pid:%d)\n", 
        rc, rc_wait, (int) getpid());
    }
    return 0;
}

在这里插入图片描述

// p5b.c wait() in the child
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/wait.h>

int main(int argc, char *argv[])
{
    printf("hello world (pid:%d)\n", (int) getpid());
    int rc = fork();
    if (rc < 0)
    {
        // fork failed; exit
        fprintf(stderr, "fork failed\n");
        exit(1);
    }
    else if (rc == 0)
    {
        // child (new process)
        int rc_wait = wait(NULL);
        printf("hello, I am child (rc_wait:%d) (pid:%d)\n", rc_wait, (int) getpid());
    }
    else
    {
        // parent goes down this path (main)
        printf("hello, I am parent of %d (pid:%d)\n", rc, (int) getpid());
    }
    return 0;
}

在这里插入图片描述

6

在这里插入图片描述

// p6.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/wait.h>

int main(int argc, char *argv[])
{
    printf("hello world (pid:%d)\n", (int) getpid());
    int rc = fork();
    if (rc < 0)
    {
        // fork failed; exit
        fprintf(stderr, "fork failed\n");
        exit(1);
    }
    else if (rc == 0)
    {
        // child (new process)
        printf("hello, I am child (pid:%d)\n", (int) getpid());
    }
    else
    {
        // parent goes down this path (main)
        /* pid_t waitpid(pid_t pid, int* status, int options);
         * if you are not familiar with this function, 
         * you can go to Baidu Baike, don’t be afraid of trouble.
        */
        waitpid(rc, NULL, WNOHANG);
        printf("hello, I am parent of %d (pid:%d)\n", rc, (int) getpid());
    }
    return 0;
}

在这里插入图片描述

7

在这里插入图片描述

// p7.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>

int main(int argc, char *argv[])
{
    printf("hello world (pid:%d)\n", (int) getpid());
    int rc = fork();
    if (rc < 0)
    {
        // fork failed; exit
        fprintf(stderr, "fork failed\n");
        exit(1);
    }
    else if (rc == 0)
    {
        // child (new process)
        close(STDOUT_FILENO);
        printf("hello, I am child (pid:%d)\n", (int) getpid());
    }
    else
    {
        // parent goes down this path (main)
        printf("hello, I am parent of %d (pid:%d)\n", rc, (int) getpid());
    }
    return 0;
}

在这里插入图片描述

8

在这里插入图片描述
pipe函数详解

// p8.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<errno.h>

int main(int argc, char *argv[])
{
    int fd[2];
    /* fd[0] points to the read port of the pipe
     * fd[1] points to the write port of the pipe 
    */
    int ret = pipe(fd);
    if (ret == -1)
    {
        perror("pipe error\n");
        exit(1);
    }
    int rc = fork();
    if (rc < 0)
    {
        // fork failed; exit
        fprintf(stderr, "fork failed\n");
        exit(1);
    }
    else if (rc == 0)
    {
        // child (new process)
        close(fd[0]);
        char *child = "I am child";
        for (int i = 0; i < 5; i++)
        {
            write(fd[1], child, strlen(child) + 1);
            sleep(2);
        }
    }
    else
    {
        // parent goes down this path (main)
        close(fd[1]);
        char msg[50];
        for (int i = 0; i < 5; i++)
        {
            memset(msg, '\0', sizeof(msg));
            ssize_t s = read(fd[0], msg, sizeof(msg));
            if (s > 0)
                msg[s - 1] = '\0';
            printf("%s\n", msg);
        }
    }
    return 0;
}

在这里插入图片描述

标签:fork,Process,printf,pid,int,API,rc,习题,include
From: https://www.cnblogs.com/astralcon/p/16792680.html

相关文章