欢迎光临
我们一直在努力

015-计算机操作系统实验报告之进程的创建!

今天给大家分享的是一个计算机网络实验报告:进程的创建!

相信学计算机的小伙伴肯定不陌生,这个实验包括了实验目的、实验内容、实验指导、实验代码及截图四个部分。

详细包括了该实验课程所需要的各个知识点。详情请看图片目录。只分享文档!

需要的点头像进主页看个人简介!需要的点头像进主页看个人简介!



以下请忽略!!!!以下请忽略!!!!以下请忽略!!!!以下请忽略!!!!

下面介绍操作系统中“进程的创建”的具体过程,分步骤说明并解释关键数据结构和相关系统调用。为便于理解,示例以类 Unix(Linux)的实现为主。

一、概念与相关数据结构(简要)

  • 进程(Process):正在运行的程序的一个实例。操作系统用 PCB(进程控制块)或 task_struct(Linux)来表示,包含 PID、状态、寄存器、指针、文件描述符等。
  • 线程与进程:线程是调度的基本单位,进程通常至少包含一个线程(主线程)。
  • 地址空间:进程的虚拟内存布局(代码、数据、堆、栈、映射区)。
  • 用户态/内核态上下文:切换时需保存/恢复的寄存器、栈指针等。
  • 资源表:打开文件、信号处理、工作目录、权限等。

二、创建进程的触发方式

  • 用户请求:fork()/vfork()/clone()、execve()(替换当前进程映像)。
  • 系统启动时:init/systemd 等由内核启动第一个用户进程。
  • 其他机制:posix_spawn(), 使用容器或内核线程创建等。

三、主要系统调用与语义(以 Unix/Linux 为例)

  • fork(): 复制当前进程(父进程),返回两次(父返回子 PID,子返回 0)。父子共享代码段,数据段按写时复制(COW)。
  • vfork(): 为提高效率,子与父共享地址空间直到 exec 或 exit,父进程暂停。
  • clone(flags, …): 更细粒度控制,指定共享或独立资源(如 CLONE_FS、CLONE_FILES、CLONE_VM 等),用于创建线程或容器。
  • execve(path, argv, envp): 用新程序替换当前进程映像,但保持 PID、某些文件描述符(若未设 FD_CLOEXEC)、信号处理等。
  • posix_spawn(): 高层封装,通常底层实现仍用 fork+exec,但更高效的实现可避免完整复制。

四、进程创建的步骤(典型 fork() 路径)

  • 用户进程调用 fork(),触发系统调用进入内核态。
  • 内核检查资源限制与权限(如 RLIMIT_NPROC、UID 等)。
  • 分配新的 PID:从 PID 池获得唯一 PID。
  • 分配 PCB(task_struct)并初始化:复制父进程的 PCB 内容(大部分字段复制,某些需要重置,如统计字段、信号处理计数等)。
  • 复制或共享资源:
    • 虚拟内存:建立新的 mm_struct。采用写时复制(COW)机制,页面表复制但物理页不复制,写时触发页复制。
    • 文件描述符表:引用计数增加(共享同一文件表),除非设置 FD_CLOEXEC。
    • 信号处理:复制信号处理器设置。
    • 环境与命令行参数:内存中指针和数据按需复制或共享。
  • 创建内核栈并设置用户上下文:为子进程准备内核态栈、设置返回值(子在内核返回 0)。
  • 将子进程放入就绪队列:设置进程状态为可运行(TASK_RUNNING),由调度器选中运行。
  • 返回用户态:父、子分别在用户态继续执行各自返回点。两者的返回值不同(父:子 PID;子:0)。
  • 后续(可选)exec:子进程通常调用 execve() 来加载新程序。exec 的主要步骤:
    • 验证并加载可执行文件格式(ELF)。
    • 释放原有地址空间(mm_struct),建立新的地址空间和用户栈。
    • 设置 argv/envp、堆栈对齐、动态链接器加载(若是动态可执行文件)。
    • 更新进程名、信号处理、CPU 寄存器,使控制转到新程序入口点(用户态)。
  • 五、写时复制(COW)细节

    • fork 时复制页表;标记所有写able 页面为只读并共享,写时产生页面错误(page fault)。
    • 页面错误处理:内核分配新的物理页面,复制内容,修改页表,恢复写权限。
    • 减少内存开销和复制时间,适合 fork+exec 模式。

    六、进程清理(退出与回收)

    • 进程调用 exit():释放用户资源(关闭文件,释放内存),改变状态为 ZOMBIE,通知父进程(SIGCHLD)。
    • 父进程调用 wait()/waitpid() 获取子退出状态,内核回收子 PCB 与 PID。
    • 若父先退出,子被 init/systemd 收养(reparenting),由其 wait 收集。

    七、内核线程与用户进程的差异

    • 内核线程没有用户态地址空间(mm_struct 为 NULL 或共享),通常通过 kernel_thread 或 clone 创建(CLONE_VM vs CLONE_THREAD)。
    • 调用路径略有不同,不需 exec。

    八、实现细节与优化

    • PID 命名空间、用户命名空间、cgroups、capabilities 影响创建与隔离。
    • posix_spawn、vfork 优化避免完整复制。
    • 线程库(pthread)通常通过 clone 创建线程,线程共享大部分资源但有独立栈。

    九、示例(伪代码流程)

    • fork():
    • syscall_entry(fork)
    • check_limits()
    • child = alloc_task_struct()
    • copy_mm_with_cow(parent, child)
    • dup_file_table(parent, child)
    • setup_kernel_stack(child)
    • enqueue_task(child)
    • return_to_user(parent, child)

    十、常见问题与注意

    • fork 在大内存进程上开销大(使用 vfork/posix_spawn 优化)。
    • COW 并非在所有情形都有效(mmap MAP_SHARED 区域、匿名非 COW 页面等)。
    • race condition:父子对共享资源并行访问需同步。
    赞(0)
    未经允许不得转载:171主机测评 » 015-计算机操作系统实验报告之进程的创建!
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址