计算机系统概论 作业5


  1. 对于如下代码: 请回答以下问题

    #include <cstdlib>
    #include <unistd.h>
    #include <cstdio>
    
    int counter = 0;
    
    int main(){
        for (int i = 0;i < 2; i++) {
            fork();
            counter++;
            printf("counter = %d\n", counter);
        }
        // 注意: 这里没有 counter++;
        printf("counter = %d\n", counter);
        return 0;
    }

    1) 程序会输出多少行? (空行不计算在内)

    答: 会输出 10 行.

    2) 程序第一行和最后一行分别会输出什么?

    答: 第一行输出 counter = 1; 最后一行输出 counter = 2.

    3) 根据系统对进程的调度情况, 程序一共有多少种可能的输出结果? (如果同一时间有若干进程在同时运行, 他们运行的先后顺序的不同可能导致输出结果不同)

    答: 程序一共有 5 种可能的输出结果.

    分别对应第一次 fork 的子线程在父线程 4counter = 2 的输出之间.

  2. 对于如下代码:

    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    
    int pid;
    
    void handler(int sig) {
    	if (sig == SIGINT && pid != 0) {
            printf("Killing Child process\n"); fflush(stdout);
            kill(pid, SIGKILL);
        }
        if (pid == 0) {
    		printf("Child process receiving Kill\n"); fflush(stdout);
    		exit(-1);
    	}
    }
    
    int main(){
    	pid = fork();
        signal(SIGINT, handler);
        signal(SIGKILL, handler);
        if (pid) {
            int status;
            waitpid(pid, &status, 0);
            int i = WEXITSTATUS(status);
            printf("child's exit status=%d\n", i);
        } else {
            while (1){
                sleep(1);
                printf("Waiting...!\n"); fflush(stdout);
            }
        }
        return 0;
    }

    在执行过程中, 如果用户按下 Ctrl+C, 请问程序在一串 Waiting…! 之后会输出什么内容, 为什么?

    答: 会输出:

    Child process receiving Kill
    Killing Child process
    child's exit status=255

    fork 后在父进程内调用 waitpid, 父进程自身被挂起.

    按下 Ctrl+C 后, 系统内核发送 SIGINT 信号至父进程与子进程, 子进程接收 SIGINT 信号, 其信号处理函数输出 Child process receiving Kill, 子进程退出.

    随后父进程恢复, 接受 SIGINT 信号, 其信号处理函数输出 Killing Child process, 最后通过 WEXITSTATUS 获取子进程退出状态, 输出 child's exit status=255.

  3. 对于如下代码, 程序将输出什么内容, 为什么? (foo.txtbar.txt 文件存在)

    int main(){
        int fd1, fd2;
        fd1 = open("foo.txt", O_RDONLY);
        fd2 = open("bar.txt", O_RDONLY);
        close(fd2);
        fd2 = open("bar.txt", O_RDONLY);
        printf("fd2=%d\n", fd2);
        return 0;
    }

    答: 会输出 fd2=4.

    进程创建时, 标准输入, 标准输出, 标准错误已分别占用了描述符 0, 1, 2; 以只读方式打开文件 foo.txtbar.txt, 可用描述符池分配 fd1 = 3, fd2 = 4; 关闭 bar.txt 后, 描述符 4 恢复到描述符池; 打开 bar.txt 后, 仍有 fd2 = 4.

  4. 在以下情形中, 分别需要使用什么 IO 方式来进行处理:

    1) 编译器读取源文件 Standard IO.

    2) 编译器生成可执行文件 Standard IO.

    3) 处理图像文件 Standard IO.

    4) 程序需要读写超大规模的文件,运行过程中可能需要处理外部信号 Unix IO.

    5) 访问网络内容 RIO.


文章作者: Chengsx
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Chengsx !
  目录