我的github链接,所有的源文件在其中
(注意:本次所有实验都在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
2 #include
3 #include
4 #include
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
2 #include
3 #include
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
2 #include
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