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

目录

  • 前言
  • 预备部分
  • 操作部分
    • 1.使用 fork 创建进程
      • 1A. 创建 10 个子进程。
      • 1B. 10 层子进程嵌套
      • 1C. 树形创建
    • 2.僵尸与孤儿进程
      • 2A. 孤儿进程
      • 2B. 僵尸进程
    • 3.线程与线程堆栈
    • 4.进程线程开销比较
    • 5.自定义shell
  • 总结

前言

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

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

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

预备部分

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

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

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

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

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


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

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

深大操作系统实验一:并发程序设计_第1张图片

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

在这里插入图片描述

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

#include 
#include 

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 软件进行:

深大操作系统实验一:并发程序设计_第2张图片

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

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

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

深大操作系统实验一:并发程序设计_第3张图片

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

在这里插入图片描述

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

深大操作系统实验一:并发程序设计_第4张图片
最后我们 kill 掉父进程 7444,使用 kill -Kill 7444,结果如下:

深大操作系统实验一:并发程序设计_第5张图片
将父进程 kill 掉,子进程也随着消失。再次启动 hello,此时 hello 换了个号 8935 了:

深大操作系统实验一:并发程序设计_第6张图片
查看 8935 号线程的内存映射信息,通过命令 cat /proc/线程id/maps 即可:

深大操作系统实验一:并发程序设计_第7张图片
比如 hello 的栈空间,虚拟变量,虚拟动态共享变量,虚拟系统调用的地址。再通过命令 cat /proc/线程id/status 进行进程状态的查看:

深大操作系统实验一:并发程序设计_第8张图片

操作部分

大的要来了。

1.使用 fork 创建进程

使用 fork() 创建子进程,形成以下父子关系:
深大操作系统实验一:并发程序设计_第9张图片
要求:并通过 /proc 文件系统,检查进程的 pid 和 ppid 证明你成功创建相应的父子关系,并用 pstree 验证其关系。

1A. 创建 10 个子进程。

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

#include 
#include 

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 个进程:

深大操作系统实验一:并发程序设计_第10张图片
然后依次查看进程 13819~13828 号的 status 信息,检查 PPid 字段以验证其父亲是哪位进程。通过命令:cat …/…/…/proc/138xx/status | head -n 10依次查看:
深大操作系统实验一:并发程序设计_第11张图片
深大操作系统实验一:并发程序设计_第12张图片

深大操作系统实验一:并发程序设计_第13张图片
深大操作系统实验一:并发程序设计_第14张图片
深大操作系统实验一:并发程序设计_第15张图片
深大操作系统实验一:并发程序设计_第16张图片
深大操作系统实验一:并发程序设计_第17张图片
深大操作系统实验一:并发程序设计_第18张图片
深大操作系统实验一:并发程序设计_第19张图片
深大操作系统实验一:并发程序设计_第20张图片

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

深大操作系统实验一:并发程序设计_第21张图片

1B. 10 层子进程嵌套

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

#include 
#include 

int main()
{
   
    for(int i=0; i

你可能感兴趣的:(操作系统,堆栈,linux,操作系统,进程,线程)