操作系统实验一:操作系统初步

操作系统实验一:操作系统初步

李许增 16281042
操作环境:arch Linux

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

1、阅读分别运行用API接口函数getpid()直接调用和汇编中断调用两种方式调用Linux操作系统的同一个系统调用getpid的程序(请问getpid的系统调用号是多少?linux系统调用的中断向量号是多少?)。

程序代码1(getpid.c):

#include<stdio.h>
#include<unistd.h>

int main()
{
	pid_t pid;
	pid = getpid();
	printf("%d\n",pid);
	return 0;
}

程序代码2(getpid_break.c):

#include<stdio.h>
#include<unistd.h>

int main()
{
	pid_t pid;

	asm volatile(
		"mov $0,%%ebx\n\t"
		"mov $0x14,%%eax\n\t"
		"int $0x80\n\t"
		"mov %%eax,%0\n\t"
		:"=m" (pid)
		);

	printf("%d\n",pid);
	return 0;
}

程序运行结果:

两个程序运行结果
通过实验程序可知:getpid系统调用号:0x14;Linux系统调用的中断向量号:int 0x80

2、上机完成习题

程序代码1(c语言实现:hello.c):

#include<stdlib.h>
#include<stdio.h>
int main()
{
	printf("hello,world!");
	return 0;
}

程序代码2(汇编实现:hello.asm):

; hello.asm 
section .data            ; 数据段声明
        msg db "Hello, world!", 0xA     ; 要输出的字符串
        len equ $ - msg                 ; 字串长度
section .text            ; 代码段声明
global _start            ; 指定入口函数
_start:                  ; 在屏幕上显示一个字符串
        mov edx, len     ; 参数三:字符串长度
        mov ecx, msg     ; 参数二:要显示的字符串
        mov ebx, 1       ; 参数一:文件描述符(stdout) 
        mov eax, 4       ; 系统调用号(sys_write) 
        int 0x80         ; 调用内核功能
                         ; 退出程序
        mov ebx, 0       ; 参数一:退出代码
        mov eax, 1       ; 系统调用号(sys_exit) 
        int 0x80         ; 调用内核功能

代码运行结果:
在这里插入图片描述
3、阅读pintos操作系统源代码,画出系统调用实现的流程图。

系统带哦用流程图

二、(并发实验)根据以下代码完成下面的实验。

程序代码:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/time.h>
#include <assert.h>
int main(int argc, char *argv[])
{
	if (argc != 2) {
		fprintf(stderr, "usage: cpu <string>\n");
		exit(1);
	}
	char *str = argv[1];
	while (1)
       	{
		sleep(3);
		int j = 100000;
		while(j > 0)
		{
			j--;
		}
		printf("%s\n", str);
	}

	return 0;
}

运行结果:

在这里插入图片描述
1、 编译运行该程序(cpu.c),观察输出结果,说明程序功能。(编译命令: gcc -o cpu cpu.c –Wall)(执行命令:./cpu)

程序功能:执行命令后提示缺少参数,程序通过C语言”printf”函数实现调用cpu的功能。

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

cpu运行了一次,每次调用输出顺序不变都是A,B,C,D,并且同时输出,证明多个程序运行是在同一时间间隔内,但是他们输出的顺序没有改变cpu在这个时间间隔内运行程序还是有顺序的,这个现象符合并发的概念。Linux为分时操作系统,所以程序执行有时间先后。

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

程序代码:

#include <unistd.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
	int *p = malloc(sizeof(int)); // a1
	assert(p != NULL);
	printf("(%d) address pointed to by p: %p\n",getpid(), p); // a2
	*p = 0; // a3
	while (1) {
		sleep(2);
		*p = *p + 1;
		printf("(%d) p: %d\n", getpid(), *p); // a4
	}
	return 0;
}

程序运行结果:

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

程序观察程序运行时变量被分配的内存地址。

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

两次运行程序分配的内存地址不相同(因为变量p分配的地址不同),不共享同一块物理内存区域,两个程序分配的pid不同所以程序不在同一个内存区域上。

3、关闭虚拟内存随机分配程序运行结果
发现两个进程分配内存相同。
在这里插入图片描述

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

程序代码:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
volatile int counter = 0;
int loops;
void *worker(void *arg) {
	int i;
	for (i = 0; i < loops; i++) {
		counter++;
	}
	return NULL;
}

int main(int argc, char *argv[])
{
	if (argc != 2) {
		fprintf(stderr, "usage: threads <value>\n");
		exit(1);
	}
	loops = atoi(argv[1]);
	pthread_t p1, p2;
	printf("Initial value : %d\n", counter);
	pthread_create(&p1, NULL, worker, NULL);
	pthread_create(&p2, NULL, worker, NULL);
	pthread_join(p1, NULL);
	pthread_join(p2, NULL);
	printf("Final value : %d\n", counter);
	return 0;
}

程序运行结果:

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

程序可以在执行过程中创建两条线程进行运行,并且调用共享的变量以观察多线程调用的结果。

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

执行结果程序运行中开了两个线程所以counter的输出应该改为输入数的二倍加入输入为n,则输出应该为2n,带式实际结果出现为部分输出小于2n当然输出结果不可能大于2n。结果出现小于2n的证明多线程调用初夏你了问题,发生了冲突。

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

线程共享变量:loops;counter;会导致意想不到的问题,事实证明多线程调用可能存在数据丢失或者数据出错的问题。

github链接: https://github.com/LiXuzeng/2019_OS_LXZ.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值