操作系统第一次作业
实验一:操作系统初步
作业题目:
1.1 (系统调用实验)了解系统调用不同的封装形式。
(1)参考下列网址中的程序。阅读分别运行用API接口函数getpid()直接调用和汇编中断调用两种方式调用Linux操作系统的同一个系统调用getpid的程序(请问getpid的系统调用号是多少?linux系统调用的中断向量号是多少?)。
(2)上机完成习题1.13。
(3)阅读pintos操作系统源代码,画出系统调用实现的流程图。
1.2
(并发实验)根据以下代码完成下面的实验。
(1)编译运行该程序(cpu.c),观察输出结果,说明程序功能。
(编译命令:
gcc -o cpu cpu.c –Wall)(执行命令:./cpu)
(2)再次按下面的运行并观察结果:执行命令:./cpu A & ; ./cpu B & ; ./cpu C &
; ./cpu D &程序cpu运行了几次?他们运行的顺序有何特点和规律?请结合操作系统的特征进行解释。
1.3
(内存分配实验)根据以下代码完成实验。
(1)阅读并编译运行该程序(mem.c),观察输出结果,说明程序功能。(命令: gcc -o mem mem.c –Wall)
(2)再次按下面的命令运行并观察结果。两个分别运行的程序分配的内存地址是否相同?是否共享同一块物理内存区域?为什么?命令:./mem
&; ./mem &
1.4 (共享的问题)根据以下代码完成实验。
(1)阅读并编译运行该程序,观察输出结果,说明程序功能。(编译命令:gcc -o thread thread.c -Wall)(执行命令1:./thread
1000)
(2)尝试其他输入参数并执行,并总结执行结果的有何规律?你能尝试解释它吗?(例如执行命令2:./thread
100000)(或者其他参数。)
(3)提示:哪些变量是各个线程共享的,线程并发执行时访问共享变量会不会导致意想不到的问题。
第1.1题解答:
(1)getpid的系统调用号是0x14,linux系统中断向量号是0x80,两种调用方式如下:
(2)两种调用方式如下。其中,linux的系统调用使用write函数。
(3)操作系统的pintos系统调用的实现如下:
第1.2题解答:
(1)根据代码和输出的信息可以看出,这个程序的作用是输出命令行参数中的内容。
(2)根据结果可以明显的看到输出的顺序与输入参数的顺序(ABCD)是不一致的。原因是因为四个程序在宏观上是一同运行的,微观上还是在cpu交替运行的,且优先级相同,先进行的程序不一定是先结束,所以这结束的顺序是不确定的,因此输出顺序也就是不确定的。
第1.3题解答:
(1)该程序的功能为:
1.程序分配了内存并打印出内存地址,然后将0放入内存的第一个位置。
2.循环并延迟一秒并递增存储在p中保存的值。
3.打印正在运行的程序的进程标识符。
(2)可以从运行结果看到,两个独立运行的程序并不共享一块物理地址。这是由于操作系统虚拟化了内存,每个进程访问自己的私有虚拟地址空间,操作系统以某种方式映射到机器的物理内存。一个正在运行的程序中的内存引用不会影响其他进程(或OS本身)的地址空间。
第1.4题解答:
(1&2)调用时输入的参数为1000。程序使用Pthread .create()创建两个线程,每个线程在worker()的例程中运行,该函数的作用是循环递增的计数器,计数区间为1。当两个线程完成时,计数器的最终值为2000,因为每个线程将计数器递1000次。 所以可以推断当循环的输入值设置为N时,程序的期望输出为2N。再用100000做参数,输出为200000,用150000为参数时,输出300000,成功验证。
参数为150000时
(3)在以上解释的基础下,增大输入的参数,会发现得到的输入不再是2N。
原因:计数器递增,需要三个指令:计数器的值从存储器加载到寄存器中、递增、存储回内存。这意味着这三条指令不是同时执行的,指令调用顺序不固定。且countor、loops这两个全局变量是被这两个线程共享的。当参数变得很大时,就会由于指令调用顺序和参数共享的缘故导致结果不符合预期。