武汉大学操作系统大作业 - 2
更新时间:2023-11-09 03:53:01 阅读量: 教育文库 文档下载
Fork、Pthread实验报告
一、学习目标
1.学习fork函数和pthread函数的使用,阅读源码,分析两个函数的机理。 2.在系统中创建一个三层次父子进程树,并具有两层次线程,并打印运行中各个执行体的处理器使用、内存使用等基本信息。
二、基本原理
1、fork函数
fork函数的函数原型是pid_t fork( void)。fork()函数的响应函数是 sys_fork()、sys_clone()、sys_vfork()。这三个函数都是通过调用内核函数 do_fork() 来实现的。
使用do_fork()函数创建一个进程大致分为如下几个过程:
(1)向系统申请在内存中分配一个 task_struct 数据结构,即进程控制块PCB, do_fork()中通过使用alloc_task_struct()实现。task_struct是LINUX内核用以管理进程的结构体,它包含了进程状态、PID、内核栈等等执行进程所必须要的资源。
(2)对PCB进行初始化操作。通过执行*p=*curren,将父进程(当前进程)的PCB内容拷贝到新进程中去,重新设置 task_struct 结构中那些与父进程值不同的数据成员,为进程分配标志号。根据参数中传入的 clone_flags 参数值,决定是否要拷贝父进程 task_struct 中的指针 fs 、files 指针等所选择的部分。
(3)将新进程加入到进程链表中去,并拷贝父进程的上下文来初始化子进程上下文。启动调度程序,通过wake_up_process(p)唤醒子进程,并放入就绪队列当中。父进程返回子进程的PID,子进程返回0。
通过do_fork()函数以及示例代码运行结果,可以了解到fork()函数的如下特点: (1)fork函数返回值Pid_t 是在头文件sys/types.h中定义的宏,在调用fork后会返回两个值,如果是子进程则返回值为0,如果是父进程则返回值大于0(为子进程的PID),如果创建进程失败则返回值小于0。
(2)通过fork函数创建的新进程是对父进程的复制,子进程的所有数据(变量、环境变量、程序计数器等)数值都和原进程一致。通过示例代码1.1可以看见父、子进程最后执行结果中count的值都是1,这是因为子进程拷贝的是父进程当前的状态, count为0,执行了‘++’操作变为1。
(3)父进程和子进程的概念是相对的,如运行结果1.2所示,p722是p719的子进程,也是p724的父进程。父进程和子进程的执行顺序是不一定的,这依赖于系统调度。子进程和父进程的可执行程序是同一个程序、上下文和数据,绝大部分就是原进程(父进程)的拷贝,但它们是两个相互独立的进程,fork()以后,子进程就相当于父进程的兄弟一样了。
(4)在运行结果1.1中可以看见子进程输出时父进程的ID为1,这是因为在子进程执行printf语句的时候,父进程已经结束了,对于没有父进程的子进程系统会将其父进程置为init(PID为1)进程。
代码示例1.1
运行结果1.1
示例代码1.2
运行结果1.2
【注】 代码示例1.1运行结果如运行结果1.1所示,示例代码1.2运行结果如运行结果1.2所示。
2、pthread函数
Pthread中定义了一系列线程操作函数、同步互斥函数,此次主要学习了pthread_create()、pthread_join()、pthread_exit()函数。
(1)pthread_create()函数用于线程创建,第一个参数pthread_t *thread用于存储创建成功的线程的ID。第二个参数const pthread_attr_t * attr 用于给定线程属性,置为NULL则使用默认属性。
pthread_create()源代码中,新进程的参数、信息均被打包到request结构中,再通过__libc_write(__pthread_manager_request, (char *) &request, sizeof(request)),将请求写入全局变量__pthread_manager_request,最后由__pthread_manager()函数创建并管理线程。
(2)pthread_join()函数用于挂起线程,第一个参数pthread_t thread,用于指定次需要等待结束的线程,当thread指定的线程没有终止,将导致调用线程挂起,直到由参数thread指定的线程终止。最后一个参数void**status是通过pthread_exit()函数传递进来的,如作业代码中主线程要等待线程1结束,而线程1要等待线程2结束。 (3)pthread_exit()函数用于结束线程,参数status将子线程的结束状态传递给主线程。主线程可以在pthread_join()成功返回后获得子线程的结束状态,并根据不同的结束状态做不同的处理。
通过运行示例代码可以发现线程的一些特点:
(1)子线程的创建顺序与子线程执行顺序是不一致,子线程的执行顺序是随机的,依赖于操作系统的调度。如运行结果2.1.1和2.1.2所示,两个子线程执行顺序是随机的。
(2)示例代码2.1中,线程1线程2对number都有写操作,所以在修改number值的时候要进行加锁和解锁的操作,避免出现结果不唯一结果。如果去掉互斥锁,可以看见如运行结果2.1.2所示number值出现了错误。
(3)线程没有独立的存储空间,同一进程下的线程共享存储空间,所以在运行结果2.1.1中我们看到number的结果是逐渐累加的,在作业代码运行结果中也可以看到线程1、2与创建他们的进程共用一个内存地址,且PID均为父进程的PID。其实,线程有各自的线程ID,可以通过pthread_self()获得。
示例代码2.1两个子线程
运行结果2.1.1
运行结果2.1.2
【注】 代码示例2.1运行结果如运行结果2.1.1和2.1.2所示。
三、实验结果
1、代码及运行结果截图
作业代码 3.1.1 第一次fork
作业代码 3.1.2 第二次fork
作业代码 3.1.3 子线程定义
正在阅读:
武汉大学操作系统大作业 - 211-09
反应器施工方案06-05
中国果蔬食品罐头行业市场前景分析预测报告(目录) - 图文01-23
买卖合同司法解释的理解与适用(王利明)05-02
电信公司毕业实习报告范文4篇05-04
浅谈学生思想道德的培养03-10
高中生物学习方法总结03-28
- exercise2
- 铅锌矿详查地质设计 - 图文
- 厨余垃圾、餐厨垃圾堆肥系统设计方案
- 陈明珠开题报告
- 化工原理精选例题
- 政府形象宣传册营销案例
- 小学一至三年级语文阅读专项练习题
- 2014.民诉 期末考试 复习题
- 巅峰智业 - 做好顶层设计对建设城市的重要意义
- (三起)冀教版三年级英语上册Unit4 Lesson24练习题及答案
- 2017年实心轮胎现状及发展趋势分析(目录)
- 基于GIS的农用地定级技术研究定稿
- 2017-2022年中国医疗保健市场调查与市场前景预测报告(目录) - 图文
- 作业
- OFDM技术仿真(MATLAB代码) - 图文
- Android工程师笔试题及答案
- 生命密码联合密码
- 空间地上权若干法律问题探究
- 江苏学业水平测试《机械基础》模拟试题
- 选课走班实施方案
- 武汉大学
- 操作系统
- 作业