概论
今天操作系统实验一的实验是对进程调度的模拟,本身没什么太大的边数。 久违的用了C++通过面向对象的方式实现了时间片轮转和优先级最高的模拟。
很久没有用C++写过面向对象的内容了,并且还涉及到了链表和指针的操作。
感觉自己的写法非常Java化,在涉及到指针的操作上,debug用了很久。诶
题目大意:
设计思路:
总体分为了PCB类,链表类,以及进程调度的启动类。
但感觉在工具类与具体的Action之间,并没很好的解耦
实体对象PCB类
感觉自己就像在写JavaBean :) ,如果是用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
//
// Created by Yisa on 2016/11/29.
//
using namespace std;
int static State_Waiting = 0;
int static State_Running = 1;
int static State_Finish = 2;
class ProcessControlBlock{
private:
int static CurrentProcessCount ;
int ProcessIndex;
ProcessControlBlock* ptr;
int PriorityNum;
int CurrentTime;
int State;
int Alltime;
public:
ProcessControlBlock(){
ProcessIndex = ++CurrentProcessCount;
ptr = NULL;
PriorityNum = rand()%5+1;
CurrentTime = 0;
State = State_Waiting;
Alltime = PriorityNum;
}
int getAllTime(){
return Alltime;
}
int getProcessIndex(){
return ProcessIndex;
}
ProcessControlBlock* getPtr (){
return ptr;
}
int getPriorityNum(){
return PriorityNum;
}
int getCurrentTime(){
return CurrentTime;
}
int getState (){
return State;
}
void setPtr(ProcessControlBlock* ptr){
this->ptr = ptr;
}
void setCurrentTime(int currentTime){
this->CurrentTime = currentTime;
}
void setState(int State){
this->State = State;
}
void setPriorityNum(int PriorityNum){
this->PriorityNum = PriorityNum;
}
};
int ProcessControlBlock::CurrentProcessCount= 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
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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
//
// Created by Yisa on 2016/11/29.
//
using namespace std;
int static Algo_RoundRobin = 1;
int static Algo_Priority = 2;
struct X {
int ID;
int PRIORITY;
int CURTIME;
int ALLTIME;
int STATE;
int NEXT;
};
bool cmp(X a, X b){
return a.ID<b.ID;
}
class ProcessList{
private:
ProcessControlBlock* head;
ProcessControlBlock* tail;
ProcessControlBlock* Ftail;
int Algo;
int ListLength;
protected:
int getAlgo(){
return Algo;
}
public:
void setListLength(int len){
ListLength = len;
}
int getListLengthn(){
return ListLength;
}
void TransList(){
for(ProcessControlBlock* cur = head;cur!=NULL;cur=cur->getPtr()){
cout<<"ID = "<<cur->getProcessIndex()<<" Pri = "<<cur->getPriorityNum()<<" CUR = "<<cur->getCurrentTime();
cout<<" ALLTIME = "<<cur->getAllTime();
cout<<" Next = ";
if(cur->getPtr()!=NULL){
cout<<cur->getPtr()->getProcessIndex();
}
else{
cout<<0;
}
cout<<" STATE = ";
if(cur->getState() == State_Running){
cout<<"R";
}
if(cur->getState() == State_Waiting){
cout<<"W";
}
if(cur->getState() == State_Finish){
cout<<"F";
}
cout<<" ptr = "<<cur->getPtr();
cout<<endl;
}
cout<<"head = "<<head->getProcessIndex()<<" tail = "<<tail->getProcessIndex()<<" Ftail = "<<(Ftail==NULL?0:(Ftail->getProcessIndex()))<<endl;
cout<<endl;
}
ProcessList(int algo){
head = NULL;
tail = NULL;
Algo = algo;
Ftail = NULL;
ListLength = 0;
}
bool IsRunning(){
if(head->getState() == State_Waiting){
head->setState(State_Running);
return true;
}
else{
return false;
}
}
void addProcess(ProcessControlBlock* curProcessPtr){
/*
* When List is Empty
*/
if(head == NULL && tail == NULL){
head = curProcessPtr;
tail = curProcessPtr;
return;
}
/*
* When Algo is RoundRobin
*/
if(Algo == Algo_RoundRobin){
tail->setPtr(curProcessPtr);
tail = curProcessPtr;
curProcessPtr->setPtr(NULL);
}
/*
* When Algo is Priority
* Insert with Priority
*/
else if( Algo == Algo_Priority){
bool isFind = false;
ProcessControlBlock* cur = NULL;
ProcessControlBlock* pre = NULL;
for(cur = head ;cur!=NULL ; cur = cur->getPtr()){
if(curProcessPtr->getPriorityNum() > cur->getPriorityNum()){
/*
* If refProcess's Priority above the curProcess'Priority
* When curProcess is the first Process
*/
isFind = true;
if(cur == head){
curProcessPtr->setPtr(cur);
head = curProcessPtr;
}
else{
pre->setPtr(curProcessPtr);
curProcessPtr->setPtr(cur);
}
break;
}
pre = cur;
}
/*
* refProcess'PriorityNum is the Minest
*/
if(isFind == false){
tail->setPtr(curProcessPtr);
curProcessPtr->setPtr(NULL);
tail = curProcessPtr;
}
}
}
void DeleteProcess(){
/*
* We always Delete Process From Head of the List
*/
if(Algo == Algo_RoundRobin){
/*
* ProcessDone
*/
ProcessControlBlock* DeleteProcessPtr = head;
if(head->getCurrentTime() >=head->getAllTime()){
head = head->getPtr();
DeleteProcessPtr->setPtr(NULL);
DeleteProcessPtr->setState(State_Finish);
/*
* When it is the first ProcessDone
*/
if(Ftail == NULL){
tail->setPtr(DeleteProcessPtr);
Ftail = DeleteProcessPtr;
DeleteProcessPtr->setPtr(NULL);
}
else{
Ftail->setPtr(DeleteProcessPtr);
Ftail = DeleteProcessPtr;
DeleteProcessPtr->setPtr(NULL);
}
return;
}
else{
head = head->getPtr();
DeleteProcessPtr->setPtr(tail->getPtr());
DeleteProcessPtr->setState(State_Waiting);
tail->setPtr(DeleteProcessPtr);
tail = DeleteProcessPtr;
}
}
else if(Algo == Algo_Priority){
ProcessControlBlock* DeleteProcessPtr = head;
/*
* Hook
*/
if(head->getCurrentTime() >=head->getAllTime()){
head = head->getPtr();
DeleteProcessPtr->setPtr(NULL);
DeleteProcessPtr->setState(State_Finish);
/*
* When it is the first ProcessDone
*/
if(Ftail == NULL){
tail->setPtr(DeleteProcessPtr);
Ftail = DeleteProcessPtr;
DeleteProcessPtr->setPtr(NULL);
}
else{
Ftail->setPtr(DeleteProcessPtr);
Ftail = DeleteProcessPtr;
DeleteProcessPtr->setPtr(NULL);
}
return;
}
else{
head = head->getPtr();
DeleteProcessPtr->setPtr(NULL);
DeleteProcessPtr->setState(State_Waiting);
ProcessControlBlock* pre = NULL;
bool IsFind = false;
for(ProcessControlBlock* cur = head ;cur!=NULL&&cur->getState()==State_Waiting;cur = cur->getPtr()){
if(DeleteProcessPtr->getPriorityNum() > cur->getPriorityNum()){
IsFind = true;
if(cur == head){
head = DeleteProcessPtr;
DeleteProcessPtr->setPtr(cur);
}
else{
pre->setPtr(DeleteProcessPtr);
DeleteProcessPtr->setPtr(cur);
}
break;
}
pre = cur;
}
if(IsFind == false){
DeleteProcessPtr->setPtr(tail->getPtr());
tail->setPtr(DeleteProcessPtr);
tail = DeleteProcessPtr;
}
}
}
}
void RunOnce(){
if(Algo == Algo_RoundRobin){
head->setCurrentTime( head->getCurrentTime()+1);
DeleteProcess();
}
else if(Algo == Algo_Priority){
head->setCurrentTime(head->getCurrentTime()+1);
head->setPriorityNum(head->getPriorityNum()-3);
DeleteProcess();
}
}
void PrintList(){
X Node[ListLength];
int Index = 0;
for(ProcessControlBlock* cur = head ;cur!=NULL ; cur= cur->getPtr()){
Node[Index].ID = cur->getProcessIndex();
Node[Index].PRIORITY = cur->getPriorityNum();
Node[Index].CURTIME = cur->getCurrentTime();
Node[Index].ALLTIME = cur->getAllTime();
Node[Index].STATE = cur->getState();
Node[Index].NEXT = (cur->getPtr()==NULL?0:cur->getPtr()->getProcessIndex());
Index++;
}
cout<<"============================================"<<endl;
cout<<"RUNNING PROC WAITING QUEUE"<<endl;
int t = 0;
if(Node[0].STATE == State_Waiting) {
printf("%d", Node[0].ID);
t++;
}
cout<<" ";
for(int i =t;i<ListLength;i++){
if(Node[i].STATE == State_Finish)
continue;
printf(" %d",Node[i].ID);
}
cout<<endl;
cout<<"============================================"<<endl;
sort(Node,Node+ListLength,cmp);
cout<<"ID ";
for(int i = 0;i<ListLength;i++){
printf("%3d",Node[i].ID);
}
cout<<endl<<"Priority ";
for(int i = 0;i<ListLength;i++){
printf("%3d",Node[i].PRIORITY);
}
cout<<endl<<"CURTIME ";
for(int i =0;i<ListLength;i++){
printf("%3d",Node[i].CURTIME);
}
cout<<endl<<"ALLTIME ";
for(int i =0;i<ListLength;i++){
printf("%3d",Node[i].ALLTIME);
}
cout<<endl<<"STATE ";
for(int i = 0;i<ListLength;i++){
if(Node[i].STATE == State_Waiting){
printf(" W");
}
else if(Node[i].STATE == State_Finish){
printf(" F");
}
else if(Node[i].STATE == State_Running){
printf(" R");
}
}
cout<<endl<<"NEXT ";
for(int i = 0;i<ListLength;i++){
printf("%3d",Node[i].NEXT);
}
cout<<endl<<endl<<endl;
}
};
启动类
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
//
// Created by Yisa on 2016/11/29.
//
class ProcessDispatch{
private:
int ListLength;
ProcessList* processList = NULL ;
int Algo;
public:
ProcessDispatch(int length,int algo){
this->ListLength = length;
this->Algo = algo;
processList = new ProcessList(algo);
for(int i = 0;i<ListLength;i++){
ProcessControlBlock* process = new ProcessControlBlock();
processList->setListLength(processList->getListLengthn()+1);
processList->addProcess(process);
}
}
void Running(){
while(processList->IsRunning()){
processList->PrintList();
processList->RunOnce();
}
processList->PrintList();
cout<<"============================================"<<endl;
}
};
主程序入口
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
map<string,int> m;
string static string_Algo_RoundRobin = "roundrobin";
string static string_Algo_Priority = "priority";
int main() {
m[string_Algo_Priority] = Algo_Priority;
m[string_Algo_RoundRobin] = Algo_RoundRobin;
cout<<"TYPE THE ALGORITHM: "<<endl;
string str;
cin>>str;
for(int i = 0;i<str.length();i++){
if(str[i]>='A'&&str[i]<='Z'){
str[i] = str[i]-'A'+'a';
}
}
ProcessDispatch* processDispatch = NULL;
processDispatch = new ProcessDispatch(5,m[str]);
processDispatch->Running();
return 0;
}