16281035-操作系统实验1

16281035-操作系统实验1

我的github链接,所有的源文件在其中

**16281035 **

(注意:本次所有实验都在Linux中完成)

一、(系统调用实验)了解系统调用不同的封装形式。

要求:1、参考下列网址中的程序。阅读分别运行用API接口函数getpid()直接调用和汇编中断调用两种方式调用Linux操作系统的同一个系统调用getpid的程序(请问getpid的系统调用号是多少?linux系统调用的中断向量号是多少?)。2、上机完成习题1.13。

http://hgdcg14.blog.163.com/blog/static/23325005920152257504165/

答:getpid的系统调用号是 14H、中断向量号是80H。
在这里插入图片描述

代码一运行结果:
在这里插入图片描述

在这里插入图片描述
代码二运行结果:
在这里插入图片描述

3、阅读pintos操作系统源代码,画出系统调用实现的流程图。
在这里插入图片描述
二、(并发实验)根据以下代码完成下面的实验。

要求:

1、 编译运行该程序(cpu.c),观察输出结果,说明程序功能。

(编译命令: gcc -o cpu cpu.c –Wall)(执行命令:./cpu)

答:程序功能:循环输出传入参数到屏幕,如果没参数,输出usage:cpu

输出结果在下面:

2、再次按下面的运行并观察结果:执行命令:./cpu A & ; ./cpu B & ; ./cpu C & ; ./cpu D &程序cpu运行了几次?他们运行的顺序有何特点和规律?请结合操作系统的特征进行解释。

答:只要不进行手动停止,CPU就一直运行。

**运行的特点:程序运行的次序是不确定的,我猜想程序是在并发执行,可能一个程序还未结束,另一个程序就已经开始,****也就是说程序间不需要等待一个程序的完成再进行下一个程序。**因此我们的四个程序在CPU内同时运行,但速度有快有慢,因此才会有这样的输出结果。

在这里插入图片描述

1 #include <stdio.h>

2 #include <stdlib.h>

3 #include <sys/time.h>

4 #include <assert.h>

5 #include “common.h”

6

7 int

8 main(int argc, char *argv[])

9 {

10 if (argc != 2) {

11 fprintf(stderr, “usage: cpu \n”);

12 exit(1);

13 }

14 char *str = argv[1];

15 while (1) {

16 spin(1);

17 printf("%s\n", str);

18 }

19 eturn 0;

20

三、(内存分配实验)根据以下代码完成实验。

要求:

1、阅读并编译运行该程序(mem.c),观察输出结果,说明程序功能。(命令: gcc -o mem mem.c –Wall)

答:程序的功能是新建进程并打印进程识别码

2、再次按下面的命令运行并观察结果。两个分别运行的程序分配的内存地址是否相同?是否共享同一块物理内存区域?为什么?命令:./mem &; ./mem &

答:内存地址不相同,不共享同一物理内存区域,因为在同一物理内存区的两个进程识别码不可能相同,他们可能是运行在不同内核里面的程序。

在这里插入图片描述

1 #include <unistd.h>

2 #include <stdio.h>

3 #include <stdlib.h>

4 #include “common.h”

5

6 int

7 main(int argc, char *argv[])

8 {

9 int *p = malloc(sizeof(int)); // a1

10 assert(p != NULL);

11 printf("(%d) address pointed to by p: %p\n",

12 getpid(), p); // a2

13 *p = 0; // a3

14 while (1) {

15 Spin(1);

16 *p = *p + 1;

17 printf("(%d) p: %d\n", getpid(), *p); // a4

18 }

19 return 0;

四、(共享的问题)根据以下代码完成实验。

要求:

1、 阅读并编译运行该程序,观察输出结果,说明程序功能。(编译命令:gcc -o thread thread.c -Wall –pthread)(执行命令1:./thread 1000)

答:程序功能:创建两个线程对counter进行累加操作,并输出初始值和累加后的值**。**

2、 尝试其他输入参数并执行,并总结执行结果的有何规律?你能尝试解释它吗?(例如执行命令2:./thread 100000)(或者其他参数。)

答:规律:可以看到当参数大到一定程度时,输出的值就不再是传进参数的2倍了,可能是因为CPU处理的过程时间太长,两个线程的运行发生了时间上的重合,其中一个线程在进行累加操作时,另一个线程读入了过时的共享变量counter的数据,造成了累加值不足的情况。

3、 提示:哪些变量是各个线程共享的,线程并发执行时访问共享变量会不会导致意想不到的问题。

在这里插入图片描述

1 #include <stdio.h>

2 #include <stdlib.h>

3 #include “common.h”

4

5 volatile int counter = 0;

6 int loops;

7

8 void *worker(void *arg) {

9 int i;

10 for (i = 0; i < loops; i++) {

11 counter++;

12 }

13 return NULL;

14 }

15

16 int

17 main(int argc, char *argv[])

18 {

19 if (argc != 2) {

20 fprintf(stderr, “usage: threads \n”);

21 exit(1);

22 }

23 loops = atoi(argv[1]);

24 pthread_t p1, p2;

25 printf(“Initial value : %d\n”, counter);

26

27 Pthread_create(&p1, NULL, worker, NULL);

28 Pthread_create(&p2, NULL, worker, NULL);

29 Pthread_join(p1, NULL);

30 Pthread_join(p2, NULL);

31 printf(“Final value : %d\n”, counter);

32 return 0;

33

猜你喜欢

转载自blog.csdn.net/qq_42452405/article/details/88578952