高级OS(十八) - 添加一个系统调用

一.题目

实验楼的实验8,首先从用户态初步感受系统调用fork(),然后从原理上理解系统调用的实现机制,回答:
1.编写实验中用户态的代码,并运行
2.在第12行执行fork()时系统进入到什么态?
3.结合视频中fork执行流的讲解,分析getpid()的执行流
4.fork()的执行对你有什么启发?
5.完成提高篇中添加一个系统,并截图(可以用模块的形式,也可以用编译内核的形式),说明遇到的问题,解决方法,收获体会(各2分)
6.关于系统调用,自己提出2个问题并回答

二.解答

1.运行结果如下图:

在这里插入图片描述

2.在第12行执行fork()时系统进入到什么态?

一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。
一个进程,包括代码、数据和分配给进程的资源。fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。

3.结合视频中fork执行流的讲解,分析getpid()的执行流

getpid(),用于获取当前进程的ID号。
(1)getpid()是一个POSIX标准的API,用于用户程序从用户态进入到内核态,在内核态读取当前进程的(tack_struct)的Pid,然后
返回给用户态的程序。
(2)getpid()函数在/usr/include/unistd.h里面声明。你可以试着找到这个声明。
(3)getpid()函数在glibc函数库里面实现。gcc 编译程序时,会到glibc函数库里面寻找getpid()的实现代码,然后编译。
[是所有API都要进入内核态吗?NO.比如字符串函数strcpy()就不会进入内核态。要请求操作系统服务的API才进入内核态。]

(1)getpid()是通过软中断的方式使程序进入内核态的。getpid()编译成汇编代码时,里面会有条这样的指令:int 0x80,当执行到这条
指令时,getpid()的工作暂停,内核开始工作。
(2)getpid()的功能是返回当前进程的ID,它本身是不能完成的,必须请求操作系统服务,让操作系统把当前进程的ID告诉给getpid().
操作系统能够提供很多服务,那么,getpid()就得告诉操作系统提供什么服务,所以,getpid()给内核一个参数__NR_getpid(系统调用号),
把__NR_getpid这个服务号(系统调用号),放在了一个寄存器eax里面。内核就从eax这个寄存器里面取出值。

4.fork()的执行对你有什么启发?

创建一个进程的系统调用很简单.我们只要调用fork函数就可以了。

#include <unistd.h>
pid_t fork();

当一个进程调用了fork以后,系统会创建一个子进程.这个子进程和父进程不同的地方只 有它的进程ID和父进程ID,其他的都是一样.就象父进程克隆(clone)自己一样.当然创建 两个一模一样的进程是没有意义的.为了区分父进程和子进程,我们必须跟踪fork的返回 值. 当fork掉用失败的时候(内存不足或者是用户的最大进程数已到)fork返回-1,否则 fork的返回值有重要的作用.对于父进程fork返回子进程的ID,而对于fork子进程返回0.我 们就是根据这个返回值来区分父子进程的.
父进程为什么要创建子进程呢?前面我们已经 说过了Linux是一个多用户操作系统,在同一时间会有许多的用户在争夺系统的资源,重要的是进程是可以并发执行。有时 进程为了早一点完成任务就创建子进程来争夺资源. 一旦子进程被创建,父子进程一起从 fork处继续执行,相互竞争系统的资源.有时候我们希望子进程继续执行,而父进程阻塞,直 到子进程完成任务.这个时候我们可以调用wait或者waitpid系统调用。

5.完成提高篇中添加一个系统,并截图(可以用模块的形式,也可以用编译内核的形式),说明遇到的问题,解决方法,收获体会(各2分)

在这里插入图片描述

6.关于系统调用,自己提出2个问题并回答

(1)中断、异常和系统调用之间的关系?

他们的源头不同,实际上源头是不同中断的外设发出的请求;而异常是应用程序意想不到的行为产生的一种错误;系统调用是应用程序请求OS提供的服务。相应方式不同,中断是异步的,而异常是同步的,系统调用既可以是同步的,也可以是异步的。处理机制也不同,中断服务程序是在内核态下运行的,而系统调用是用户发出请求之后等待OS来给他提供服务。

(2)为什么要系统调用

实际上,很多已经被我们习以为常的C语言标准函数,在Linux平台上的实现都是靠系统调用完成的,所以如果想对系统底层的原理作深入的了解,掌握各种系统调用是初步的要求。进一步,若想成为一名Linux下编程高手,也就是我们常说的Hacker,其标志之一也是能对各种系统调用有透彻的了解。

即使除去上面的原因,在平常的编程中你也会发现,在很多情况下,系统调用是实现你的想法的简洁有效的途径,所以有可能的话应该尽量多掌握一些系统调用,这会对你的程序设计过程带来意想不到的帮助。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值