操作系统实验

记录操作系统课程的几个实验

实验一_进程的同步与互斥

通过学习和分析基础例子程序,使用windows进程和线程编程(也可以采用Java 或Unix/Linux的POSIX线程编程)实现一个简单的生产者/消费者问题的程序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>

std::mutex mtx;//锁
std::condition_variable cv;//条件变量

int cargo = 0;//货物数
bool shipment_available()//是否有货
{
return cargo != 0;
}
// 消费者线程.
void consumer(int n)
{
for (int i = 0; i < n; ++i) {
std::unique_lock <std::mutex> lk(mtx);
cv.wait(lk, shipment_available);//若无货物被阻塞直到被唤醒
std::cout << "消费了"<< cargo << std::endl;
cargo = 0;
std::this_thread::sleep_for(std::chrono::milliseconds(250));//睡眠250毫秒
}
}

int main()
{
std::thread consumer_thread(consumer, 10); // 建立消费者线程.
// 主线程为生产者线程, 生产 10 个物品.
for (int i = 0; i < 10; ++i) {
while (shipment_available())
std::this_thread::yield();//放弃本线程的CPU时间片,允许其他线程运行
std::unique_lock <std::mutex> lk(mtx);
cargo = i + 1;
std::cout << "生产了"<< cargo << std::endl;
cv.notify_one();//唤醒等待线程
std::this_thread::sleep_for(std::chrono::milliseconds(100));//睡眠100毫秒
}
consumer_thread.join();
return 0;
}

实验二_处理机调度

设计一个按优先权调度算法实现处理器调度的程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <iostream>
#include <queue>
using namespace std;

class PCB
{
public:
char name[10]; /*进程名*/
int runtime; /*运行时间*/
int priority; /*优先级*/
char state; /*状态*/
PCB * next; /*指针*/
void status() const
{
cout<<name<<"\t"<<runtime<<"\t\t"<<priority<<"\t\t"<<state<< endl;
}
};

class PCBSortCriterion { /*优先准则*/
public:
bool operator()( const PCB & p1, const PCB & p2 ) const
{
return(p1.priority < p2.priority);
}
};

int main()
{
int number=5;/* 进程数 */
PCB * pcb = new PCB[number];
PCB * p1 = new PCB[number];
PCB p;
int i;
cout << "NAME,RUNTIME,PRIORITY" << endl;
for ( i = 0; i <= number - 1; i++ )
{
cin >> pcb[i].name;
cin >> pcb[i].runtime;
pcb[i].state='R';
cin >> pcb[i].priority;
}

typedef priority_queue<PCB, vector<PCB>, PCBSortCriterion> pQueue;

pQueue q,temp;

for ( int j = 0; j <= number - 1; j++ ) /*建立优先队列 */
{
q.push( pcb[j] );
}
cout << "初始状态:" << endl;
cout<<"NAME\t"<<"NEEDTIME\t"<<"PRIORITY\t" <<"STATE\t"<<endl;
temp = q;
while ( !temp.empty() )
{
p = temp.top();
p.status();
temp.pop();
}
cout << endl;

int n= 0,m= 0;
while ( !q.empty() )
{
cout << "CPUTIME:" << ++n<<" ";
p = q.top();
cout << q.top().name << "!" << endl;
cout<<"NAME\t"<<"NEEDTIME\t"<<"PRIORITY\t" <<"STATE\t"<<endl;

p.runtime -= 1;
p.priority -= 1;
q.pop();
if ( p.runtime != 0 ) /*继续入队*/
{
q.push( p );
}else {
p.state = 'Z';
p1[m++] = p;
}

temp = q;
while ( !temp.empty() )
{
p = temp.top();
p.status();
temp.pop();
}
if ( m > 0 ) /* 输出完成信息 */
for ( i = 0; i <= m - 1; i++ )
p1[i].status();
cout << endl;
cout << endl;
}
cout << "完成" << endl;
system( "pause" );
return 0;
}

实验三_存储管理

1.模拟分页式存储管理中硬件的地址转换和产生缺页中断

Page.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package ex3;

public class Page {//页表
private int pageId;//页号
private int flag;//标志,1则表示该页已经在主存
private int areaId;//主存块号

public Page(int pageId, int flag, int areaId) {
this.pageId = pageId;
this.flag = flag;
this.areaId = areaId;
}

public int getPageId() {
return pageId;
}

public void setPageId(int pageId) {
this.pageId = pageId;
}

public int getFlag() {
return flag;
}

public void setFlag(int flag) {
this.flag = flag;
}

public int getAreaId() {
return areaId;
}

public void setAreaId(int areaId) {
this.areaId = areaId;
}

}

Operation.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package ex3;

public class Operation {
private static int fifoindex=0;//操作
private static int optinalIndex=0;
private int pageId;//页号
private int pageAddress;//业内地址

public Operation(){

}

public Operation(int pageId,int pageAddress){
this.pageId=pageId;
this.pageAddress=pageAddress;
}

public int getPageId() {
return pageId;
}

public void setPageId(int pageId) {
this.pageId = pageId;
}

public int getPageAddress() {
return pageAddress;
}

public void setPageAddress(int pageAddress) {
this.pageAddress = pageAddress;
}

boolean flag(Page page[],Operation op){
if(page[op.getPageId()].getFlag()==1)
return true;
return false;
}

//输出页表
void printPageTable(Page page[],Operation op,Operation op2,String oper){
System.out.println("页号 "+"标志 "+"主存块号");
for(int i=0;i<7;i++){
System.out.print(page[i].getPageId()+page[i].getFlag()+page[i].getAreaId());
}
System.out.println("");
System.out.println("指令为"+oper+op.getPageId()+" "+op.getPageAddress());
System.out.println(op2.getPageId()+" "+op2.getPageAddress());
}
//输出
void print(Page page[],Operation op,Operation op2,String oper){
int index1=0,index2=0;
for(int i=0;i<7;i++){
if(op.getPageId()==page[i].getPageId())
index1=i;
if(op2.getPageId()==page[i].getPageId())
index2=i;
}
if(oper.equals("读")){
System.out.println("("+page[index1].getAreaId()+op.getPageId()+")");
System.out.println("("+page[index2].getAreaId()+op2.getPageId()+")");
}else{
System.out.println("...");
}
}

//调入主存
void move(Page page[],Operation op){
page[fifoindex].setFlag(0);
page[fifoindex].setPageId(op.getPageId());
fifoindex++;
fifoindex=fifoindex%7;

}

void fifo(Page page[],Operation op,Operation op2,String oper){
if(!flag(page,op)){
move(page,op);//不在内存则调换
}
if(!flag(page,op2)){
move(page,op2);
}
printPageTable(page,op,op2,oper);
print(page,op,op2,oper);
System.out.println();

}
}

Main.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package ex3;

public class Main {

public static void main(String[] args) {
Page A=new Page(0,1,5);
Page B=new Page(1,1,8);
Page C=new Page(2,1,9);
Page D=new Page(3,1,1);
Page E=new Page(4,0,0);
Page F=new Page(5,0,0);
Page G=new Page(6,0,0);
Page page[]={A,B,C,D,E,F,G};

Operation a=new Operation(0,070);
Operation b=new Operation(1,050);
Operation c=new Operation(2,015);
Operation d=new Operation(3,021);
Operation e=new Operation(0,056);
Operation f=new Operation(6,040);
Operation op[]={a,b,c,d,e,f};

Operation o=new Operation();

}

}

2.用先进先出(FIFO)页面调度算法处理缺页中断

1
//没写

实验四_文件系统

用高级语言编写和调试一个简单的文件系统,模拟文件管理的工作过程

User.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package ex4;

public class User {
private String name;
private String password;

public User(String name, String password) {
this.name = name;
this.password = password;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

}

FileOperation.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
package ex4;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;

//文件操作类
public class FileOperation {

private String address = "D:\\server\\";//指定目录
private File file;//新建文件
private int num;//操作选项
private String fileName;//新建文件名
private String username;

public FileOperation(String user){
this.address=this.address+user+"\\";//路径设置为用户目录
fileOperate();
}

public void fileOperate() {
file = new File(address);
file.mkdirs();
System.out.println("1:创建文件");
System.out.println("2:读取文件");
System.out.println("3:写入文件");
System.out.println("4:删除文件");
System.out.println("5:列文件目录 ");
System.out.println("6:退出 ");

System.out.println("请输入:");
//操作文件的选项数字
Scanner input = new Scanner(System.in);
try{

num = input.nextInt();

}catch(Exception e){
System.out.println("请重新输入");
fileOperate();
}

switch(num){

//创建文件
case 1:
System.out.println("当前目录:"+address);
System.out.println("创建文件: ");
System.out.println("输入文件名字(包括后缀):");
fileName = input.next();
File f1 = new File(address+fileName);
if(f1.exists()){
System.out.println("文件已经存在");
}
else{
try {
f1.createNewFile();
System.out.println("创建成功");
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("操作成功");
fileOperate();
break;

//读取文件
case 2:
System.out.println("当前目录:"+address);
System.out.println("读取文件: ");
System.out.println("输入文件名:");
fileName = input.next();
File f2 = new File(address+fileName);
String str;
BufferedReader buffer = null;
try {
FileReader ins = new FileReader(f2);
buffer = new BufferedReader(ins);
System.out.println("文件内容:");
try {
while(null != (str = buffer.readLine())){

System.out.println(str);
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
buffer.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("操作成功");
fileOperate();
break;

//写入文件
case 3:
System.out.println("当前目录:"+address);
System.out.println("写入文件: ");
System.out.println("输入文件名:");
fileName = input.next();
File f3 = new File(address+fileName);
System.out.println("输入文本内容:");
String str1 = input.next();
FileWriter wrs = null;
try {
wrs = new FileWriter(f3);
} catch (IOException e) {
e.printStackTrace();
}
BufferedWriter buffer3 = new BufferedWriter(wrs);
try {
buffer3.write(str1);
buffer3.flush();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("操作成功");
fileOperate();
break;

//删除文件或目录
case 4:
System.out.println("当前目录:"+address);
System.out.println("删除文件: ");
System.out.println("输入文件名:");
fileName = input.next();
File f4 = new File(address+fileName);
if(f4.isFile()){
if(f4.exists()){
f4.delete();
System.out.println("文件删除成功");
}
else{
System.out.println("文件不存在");
}
}
else{
System.out.println("文件不存在");
}
System.out.println("操作成功");
fileOperate();
break;

//查看文件目录
case 5:
System.out.println("操作目录 :"+address);
System.out.println("查看文件:");
String[] files = file.list();
for(int i = 0;i < files.length;i++){
File f6 = new File(address+files[i]);
if(f6.isDirectory()){
System.out.println("文件夹 :"+files[i]);
}
else{
System.out.println("文件 :"+files[i]);
}
}
System.out.println("操作成功");
fileOperate();
break;

//退出
case 6:
System.out.println("程序已退出,注销成功!");
System.exit(0);
break;
default: fileOperate();
}
}

}

Main.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package ex4;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {
public static void main(String[] ars) {
new Main();
}
//登陆账号1,密码1
public Main() {
List<User> users = new ArrayList<User>();//用户集合
for(int i=1;i<=10;i++){//添加十个用户账号密码分别是数字1-10
User user=new User(String.valueOf(i),String.valueOf(i));
users.add(user);
}
Scanner input = new Scanner(System.in);
System.out.println("用户名:");
String str = input.next();
for(User u:users){
if(u.getName().equals(str)){
System.out.println("密码:");
input = new Scanner(System.in);
String password = input.next();
if(u.getPassword().equals(password)){
System.out.println("登录成功");
FileOperation myfile = new FileOperation(u.getName());
}
else{
System.out.println("密码错误");
new Main();
}
}
else{
System.out.println("用户不存在");
new Main();
}
}
input.close();
}
}