深大操作系统实验一:并发程序设计

本文详细记录了一次深大操作系统实验,涵盖了并发程序设计的多个方面,包括使用 fork 创建进程、孤儿与僵尸进程、线程与线程堆栈的比较,以及进程线程开销的探讨。实验中通过编写C程序,运用Linux命令行工具如top、ps、pstree等,展示了进程的创建、关系和状态,以及线程堆栈的差异。此外,还讨论了如何设计一个简单的shell程序,实现内部命令和外部命令的执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

第一个实验就把我干碎了!好大的压力呀。操作系统像一座大山,压在我的狗脑子上,一点气都喘不过来。

在无数次的摆烂,抄代码,百度之后,我最终还是挺过来了,并且踉跄地把实验写完。我踩了无数个坑,分享一下我自己的实验思路。

你需要一台 linux,并且安装了 ps,pstree 等命令,他们属于 psmisc 包。

预备部分

学习 top、ps、pstree 和 kill 等命令的使用。

能通过 top 和 ps j 命令查看进程号、父进程号、可执行文件名(命令)、运行状态信息,能通过 pstree 查看系统进程树;

能通过 kill 命令杀死制定 pid 的进程。

学习 /proc/PID/maps 的输出信息。

了解 /porc/PID/status 中各项内容的。


这个直接一路打命令就完事了。。。直接贴过程:

使用 top 命令查看各进程的系统资源占用情况:

在这里插入图片描述

再来使用 ps 命令,查看当前进行的进程信息快照:

在这里插入图片描述

我们编写一段简单的 c 程序。产生两个进程,并且通过 getchar() 进行阻塞。将该文件保存为 1.c,文件的内容如下:

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

int main()
{
   
    pid_t pid = fork();

    if(pid < 0) printf("error!");   // error ckeck
    if(pid == 0) getchar();         // child progress
    if(pid > 0) getchar();          // parent progress

    return 0;
}

然后将程序上传到云服务器,这里通过 WinSCP 软件进行:

在这里插入图片描述

注:
如果你是虚拟机,那直接传磁盘就好了
这里我是租的云服务器

然后使用命令 gcc 1.c -o hello 进行编译:
在这里插入图片描述

随后执行该文件,通过命令 ./hello & 执行,此处 & 表示在后台执行即可。这里比对前后进程信息,可以发现我们产生了两个进程:

在这里插入图片描述

然后使用 pstree 命令查看进程之间的关系,我们选择 7444 号进程。命令为:pstree -p 7444,可以看到结果如下:

在这里插入图片描述

7444 号进程产生了 7445 号子进程!也可以通过 pstree -p 来查看完整的系统进程树并且确定 hello 的位置:

在这里插入图片描述
最后我们 kill 掉父进程 7444,使用 kill -Kill 7444,结果如下:

在这里插入图片描述
将父进程 kill 掉,子进程也随着消失。再次启动 hello,此时 hello 换了个号 8935 了:

在这里插入图片描述
查看 8935 号线程的内存映射信息,通过命令 cat /proc/线程id/maps 即可:

在这里插入图片描述
比如 hello 的栈空间,虚拟变量,虚拟动态共享变量,虚拟系统调用的地址。再通过命令 cat /proc/线程id/status 进行进程状态的查看:

在这里插入图片描述

操作部分

大的要来了。

1.使用 fork 创建进程

使用 fork() 创建子进程,形成以下父子关系:
在这里插入图片描述
要求:并通过 /proc 文件系统,检查进程的 pid 和 ppid 证明你成功创建相应的父子关系,并用 pstree 验证其关系。

1A. 创建 10 个子进程。

循环 10 次,每次都 fork 一下即可,下面是代码:

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

int main()
{
   
    for(int i=0; i<10; i++)
    {
   
        pid_t pid = fork();
        if(pid < 0) printf("error!");   // error ckeck
        if(pid == 0) break;             // child progress
        if(pid > 0) continue;           // parent progress
    }
    getchar();  // prevent exit

    return 0;
}

将上述代码保存为 t1a.c,意为第一题的 a 部分。然后编译并且执行该代码,可以看到产生了 1+10=11 个进程:

在这里插入图片描述
然后依次查看进程 13819~13828 号的 status 信息,检查 PPid 字段以验证其父亲是哪位进程。通过命令:cat …/…/…/proc/138xx/status | head -n 10依次查看:
在这里插入图片描述
在这里插入图片描述

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

可以看到 10 个子进程的父进程都是 13818,也可以通过 pstree 来验证。执行命令:pstree -p 13818 可以发现 10 个子进程:

在这里插入图片描述

1B. 10 层子进程嵌套

只要在 A 题的基础上交换一下父子进程两个 if 即可。如果是父进程我们直接 break,而子进程则继续 continue,继续产生子子进程。

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

int main()
{
   
    for(int i=0; i<10; i++)
    {
   
        pid_t pid = fork();
        if(pid < 
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值