- A0 @$ |- h. b' O0 S7 }2 u$ S3 A, K/* Short Job First 短作业优先算法 */0 o$ Q. r! s% s) h2 z
class SJFSchedulingAlgorithm : public SchedulingAlgorithm;- S! @+ `( |0 w: \: ^( d/ s+ r
8 R3 Y, S% e2 ]- r w! \/* Highest Response Ratio Next 高响应比优先算法 */ ; k' Z" ? u% D, [- w* K" Uclass HRRNSchedulingAlgorithm : public SchedulingAlgorithm;3 B7 w% n2 X: [: U4 `# Z5 S% s
1( a+ W0 a4 D- A* u. K- Y
2# q' \$ e6 u% h" a5 k5 q
3% W' z X z9 W- N# @6 Y
4 % A0 @5 D/ X1 ^. x, m2 j5 : @2 ?; I6 _/ c% k6 ; s; g5 M8 F; ~0 D% W7 6 }: K s& S* h& w$ \! N81 i# \$ b% J+ l( W& _6 e2 \
9! ]$ S) z$ c D! Q1 Q1 }
10 $ @2 ~: ^* Y# w+ w2 z8 R! b11: _$ e p1 X# g- M& h8 \
4.2.2 FCFS% k) B' M. w4 Q& ]
因为这里使用优先级队列来实现,所以我们只需要为每种算法定义不同的比较函数即可,比如对于FCFS算法来说,它的比较算法就是比较该作业提交的时间。 r" ?9 G# s$ S5 g2 Y5 K% `& b* j, f$ j3 F, | M
// First-Come First-Served$ Z: ^3 r8 i& k$ \) d# n
class FCFSSchedulingAlgorithm : public SchedulingAlgorithm( q* g1 b9 V9 y9 M
{+ X* _* B* \; x$ o0 A
public: 2 o. ^6 `2 N4 y* u! Y struct PriorityCmp * a1 N7 u; n( O; b+ | {/ G& P1 v* e9 {1 p& p$ U8 [
bool operator()(const JCB j1, const JCB j2)- x, D- a9 U) V: r |8 u5 s
{ + n7 ~9 i2 q3 V' Y/ _" ` return j1.submit_time > j2.submit_time;3 c. c6 z. N: M) e/ W
}' m9 T5 |$ T" D/ n6 r4 c
};- m1 o" }& ^5 ?# _7 H& W
0 z: b0 r9 o; H- S: R- h FCFSSchedulingAlgorithm(){} , ?) y- y1 Z7 f" ~}; / l( |/ ?& _+ ~) a" j: o1 ( ^9 l& O; q! w6 a2 [2. r7 @! k6 p- ?5 R" L
3 5 }5 l% b. M3 w" b/ ]8 w7 t4' C3 J. I6 i' A! |6 j. T
5 ; L- ]" I; S- [- x% G62 H0 t$ S, M# K" D
7: C m1 Z% D# P0 B' P# H
84 R$ `2 c% M* m" w8 E I, s
9/ b, I7 J$ P' N8 `; F, R/ q7 v
102 x' q1 z9 X+ I3 H2 L( N$ W! \
11' s% j s: R8 h& K3 L
128 v0 u/ o) G/ o) `. g+ P- a5 H O
13/ ~5 L, l# \0 `8 {; }
149 B. ? b0 X, r0 L x
4.2.3 SJF1 I9 g5 q1 ?' W
对于SJF算法来说,它的比较函数就是比较作业的时间长度(时间越短优先级越高)。- C) T+ _! e' n! M5 f* C2 h. b+ |& j
" P" y- `6 V- G4 j4 W// Short Job First % u+ S' o* {9 i5 vclass SJFSchedulingAlgorithm : public SchedulingAlgorithm # g* T! |3 @& I" d% A1 U{+ k" g! Q0 j3 A3 w& ?
public:. d) I- r! g+ c4 u6 l2 q
struct PriorityCmp U/ h- u5 d% d+ t5 o3 T {7 B. l7 s3 R$ ?( a1 u& m4 u
bool operator()(const JCB j1, const JCB j2)" Y$ o- R( W& c5 t8 e
{: @" o8 f/ H& d# V& e ]
return j1.required_running_time > j2.required_running_time; 8 I8 C9 a. J7 k& e; @; ~1 l# T } 7 m) v4 b9 Q- `$ n! o8 H/ s. k }; " ]: q0 q6 k- d$ X3 s ) G4 }/ ?0 [; s SJFSchedulingAlgorithm(){}2 [& d( @0 e4 j1 ~) \- o
}; 3 h7 N z" b; \, V10 [: [3 L# W! v) e$ B: R7 n8 M' o, f, w
2' w8 _( x: k! u6 [: \
3! B5 `9 W4 [+ _4 [' Q6 z6 n; g
4 + G3 [% t# s5 h5 6 N }0 l) {! G$ K6. U8 r* _' q$ r; L; [1 z
7 4 ~, Z- ~' ]6 ~7 A+ x! R; S8 & a! a0 B: c7 M/ M; Q$ X% V) z0 K8 }9 4 n: c3 S9 h& V6 Y: O' }- T10 * @& R. f) |+ a6 m11 : V2 }* q& i( J! W12+ s5 h/ T/ e0 E% d% }
13 ; O6 [9 J# N9 H1 f14 ! H" n4 j' S+ _7 Q% u4.2.4 HRRN 5 a! [7 t: P' b" ? {+ E1 H1 e) U 该算法的比较函数比较的是每个作业的响应比:(等待时间+要求服务时间)/要求服务时间,响应比越高,优先级越高,越优先被调度。9 t p- G1 o: \/ W% f% @$ M
) Q3 z9 z! `) j
// Highest Response Ratio Next 5 {# `& [/ I) D; r' rclass HRRNSchedulingAlgorithm : public SchedulingAlgorithm % Q$ F! M0 V; Q) k/ a' n+ z7 `{# R9 C* F: x- Q L# ?
public: , d- s' N0 d3 {) L: t: L struct PriorityCmp - I4 B0 J# M6 Q ~" q+ j3 z { ' y0 x, q% |8 N4 C0 v, `2 a double getPriority(JCB jcb) 8 ~% w; F! E- u/ [& k5 ^! L { $ \2 C7 d1 B7 \0 D. P return ((cur_time - jcb.submit_time) + jcb.required_running_time) / jcb.required_running_time; 8 u( _& |, c! P" f2 p* f5 b }/ F M- d1 b( S5 D U1 J0 w, X
. v; e, T7 N! N* R" W
bool operator()(const JCB j1, const JCB j2), {5 ?* o$ R5 O8 b0 T0 c
{ 6 V2 J. Z2 C% I6 a. D; y return getPriority(j1) > getPriority(j2); , l2 ~7 `5 C+ a# Z/ p, R( ^1 X, Y" P }, T$ t8 l' S8 V' K3 z9 b6 A7 D
}; 2 j. {6 b# e4 K( c , m$ o7 O" E4 f HRRNSchedulingAlgorithm(){}+ n# L _* |5 x5 L0 X$ f; q3 f
};9 M9 A( \# s% U4 l7 _
11 Y! Z% |* {9 A, y/ j, r
2 0 r/ t( v0 X; y3 : K7 {9 x; N8 @, n, x! R) D4 m {0 c2 D, v) w3 d
5! M/ M7 N% {/ Z) V1 Q/ S5 [# K
6$ x1 l. q2 ^' I. k7 n1 J
7 4 _* r( g1 ? |1 f+ Y) h. _8* v( e! B2 f- c, b% R. B# I
9 ' Z1 C" u$ |" B1 h, w10 1 Z( V/ Q, C% D; c11 ; B% @% S* N6 X* {: r) C/ p12 6 `9 F7 T7 Z1 r139 ^. o u* {) Q4 \2 S0 B
14 ( O' B4 P! r+ z5 P @15( ^% ]3 }9 q8 E0 X1 S! t
16 % H3 V- ]- v! N/ Y, N2 z9 P9 D178 ^6 h6 M4 m* y
18 6 _; E% q: v* I& q& O3 N7 J' E19* {* c& ]% e5 ~ X
4.3 多道批处理系统 + O$ c8 [8 d: l4 o4.3.1 FCFS + PSA / |( b8 D Z6 q' [8 d _+ C 对于多道批处理系统来说,情况会复杂一些,因为对于多道批处理系统,除了作业的调度还存在进程的调度,也就是作业调度决定该任务能不能使用处理机(有没有资格),但就算该任务被调度了,因为多道批处理系统,还需要考虑相关的资源,因此能不能使用到处理机,还要看进程的调度。 ; o ?2 @: h; M! i% r 因此在这里对于作业调度采用了FCFS算法,而对于进程的调度采用了PSA算法(静态优先级,可抢占),并且没有继续使用实验一中的进程调度算法的代码,而是重新写了一遍。! A8 |/ m" i5 H2 d, A7 |
所有的任务初始会被存放在 back_queue 中,而就绪的任务和正在运行的任务都存储于 psa_ready_queue 中,等到 psa_ready_queue 中存在空间时,会通过任务调度算法从 back_queue 中选择合适的任务进行调度,当任务(准确说是进程)被调到 psa_ready_queue 中后,会根据它的优先级判断它是否能够优先运行,如果不能就只能保持就绪状态,一直等到优先级高的进程运行完毕后再运行。 w8 C- u3 ~" v7 P
因为这部分代码的逻辑比较复杂,所以就不在这里单独罗列了,具体可见下面的代码实现。需要注意的是多道批处理系统代码逻辑中被注释掉的代码为测试代码,可以使用其来对代码的准确性进行测试。% c3 G3 v! X; D3 j% q
# a0 S1 b1 {- ^6 V) V- M- c五、代码实现8 `! Y5 i* d& ~0 W v; b! g
#include <iostream>; ?. {- |0 E) T+ O- P
#include <string>. L. ?" C5 U3 q7 f! p
#include <vector> 3 k4 q7 K1 P5 }6 c% T#include <queue> " J4 P, k1 r# Y& b* t \+ q- P#include <cstdlib># x @9 b* q& x) W2 M
#include <ctime> 7 m6 J& x5 w3 J, O3 B2 ]#include <unistd.h> 2 h7 N" ?2 X" j#include <iomanip> 4 l. t. P0 B0 C8 M 6 ]: ^% Y7 S6 @# C/ W/ i: ntypedef int TimeSlice; ) j% l1 `$ N2 R( d9 L2 Itypedef int Resource; + T! s& e9 ^& v# ntypedef std::queue<TimeSlice> * JobTimeSeries; ' F4 P' u! Z% Q @! ~ 2 w0 W. V! k5 E3 J( a6 jTimeSlice cur_time = 0; 5 z4 ]7 U* R f$ X0 Zint average_turnaround_time = 0; : F9 {5 _5 @0 T) G4 qdouble average_power_turnaround_time = 0;1 u4 m) Q7 C; X/ f6 a. B& j
, ?( r+ @) z& `, _
enum ProcessStatus ( U* B( h9 ~8 `- S! g2 o{ ' o, p2 M9 x B2 s' C0 L Ready = 0, 5 \# V6 @ G- s k Running = 1,' W" ^$ D3 t4 F2 }( @: b
//Finish = 21 _! c: T5 B* {0 U S/ |2 y5 ?
};8 B, u9 n7 ?4 U9 k2 \8 t8 I# n
! t8 K2 [) X5 \3 {. N# F6 itypedef int Pid; 9 G! r0 P0 W% K( n, Ktypedef int TimeSlice; ! }. k7 d! J* W/ E( Ptypedef int Priority;5 Y: c5 R# W* c. Y8 [- R5 `4 y6 m
* c4 G7 `- V i0 x: Q+ d. C
struct JCB; ( f% `: t7 }. v jtypedef JCB * JCBptr; ( V2 ?* V$ t) I; m, i6 g ; N; |) ~$ _; q6 istruct PCB . @9 t- @0 b$ v' Y% _{ 0 \1 w# @! ]: n# J) V. N+ {; V PCB(JCBptr jcb_) : jcb(jcb_){} . Q4 l: S- v, t5 A2 e5 o) r* C Pid pid; ; g9 d- ^' {3 k3 }$ k" m ProcessStatus status;; z+ r- R; f+ \7 b) H- w4 G) H
Priority priority; 2 H. H' r! p3 b5 w/ h$ j" ?; u JCBptr jcb;& i6 S9 [3 h% Q/ @) ?& @1 Y& _. b
}; 2 c `3 _$ Y8 F) x ) [1 N; N# P! g% w0 }9 i$ Wtypedef PCB * PCBptr;" P4 g. a9 N! p) |+ D
p% B# I" z; q
enum JobStatus # X1 D3 }; P. {{ T' m/ z; i1 G0 h9 e
Wait = 0, 8 u$ @: j P2 l8 p; d* D Run = 1,0 [+ }% M) U. T* `6 l( q6 v$ Y
Finish = 2 ] c0 p: p/ j0 @4 a' |! ~- e4 p
};* A; P' u! ~% c; X6 U
8 \2 M7 a+ t. W0 ^ W5 R 8 i- t2 a E' }, N! Y2 V average_turnaround_time += turnaround_time; * f. J! a7 ?, {3 D- B average_power_turnaround_time += power_turnaround_time;8 [9 D$ k5 i! e
" K. y9 ]9 w Y4 S3 o return true; ; i. k0 d. z. {& G/ [! q# K* q- \ } ' D0 a- M/ [- K. {. |! E0 f* t& y1 S9 n: d3 M( Q. d; O r8 M
static inline bool printJobData(const JCB jcb, bool isMul)( x& B5 X# g @7 M3 r+ w: L
{6 o$ {; x# X7 A
TimeSlice turnaround_time = jcb.finish_time - jcb.submit_time; W- z3 ~# S% Q9 @+ v+ G9 n
double power_turnaround_time = turnaround_time / (jcb.required_running_time / 1.0); . \9 }7 }' u1 o7 ]5 j! r" \4 c( h. A8 p) |* w2 K! e+ i; z9 }$ z) H1 n
std::cout << "[Data] " << jcb.job_name << " "' L$ W o4 {/ l& j' S! c; l
<< " Finish time: " << jcb.finish_time << " " 8 H* j |/ p# X+ H: y << " Turnaround time: " << turnaround_time << " "# Z% N( ?8 C5 w z$ L: y
<< " Power turnaround time: " << std::setprecision(2) << power_turnaround_time << std::endl; ' T8 O1 w- E: B' |( n: [2 W p/ o1 D/ A9 f+ \/ W1 y0 }6 O5 [3 z/ ]5 u6 Q* ]7 k
average_turnaround_time += turnaround_time;/ d: p& ?4 U T+ x' D
average_power_turnaround_time += power_turnaround_time; + j" I8 o. ~0 `/ }* M* D! w : e9 ^6 f3 G4 h, \ return true;' S! n# [7 U) c# n, ]8 y, x
} & Z5 s4 b& r q2 O4 I+ q7 ]};- Y5 Y( C5 V1 ]! i6 Y' L
' W/ }* Y5 |; M, |$ y' _2 Y" B
class SchedulingAlgorithm . l- M6 k% ?) h2 `, K) S& p{5 J$ w$ _, I% l$ O
public:& o# m( O" y1 j8 Q5 W! j ?
& o9 P' M( j8 f% Q; U// virtual bool initPCB(std::priority_queue<JCB, std::vector<JCB>, std::less<JCB>> * ready_queue, int process_num) = 0; 6 t9 |+ m5 z- \: e0 }1 q. j// virtual bool processPCB(JCB & pcb) = 0;; \2 M+ G d( V3 U- z) e* w% ~& Q
}; : n6 a; l! [" P- U* l( o. z* L5 ]1 M7 R0 \
// First-Come First-Served+ J, k% q7 J& j$ x, n4 u
class FCFSSchedulingAlgorithm : public SchedulingAlgorithm J1 P* b5 T1 j3 L. e* a' L' ~{ 2 g7 L7 [8 y, k0 Lpublic:/ G2 Y w% F% v' o9 [
struct PriorityCmp, q8 [' Y' S0 z& |- j6 r# s
{ 7 B7 \; ^4 x8 q7 m1 ` bool operator()(const JCB j1, const JCB j2) % ^3 h: e, I/ u( O {; h; n" m# ?2 ^$ l ~! t. W
return j1.submit_time > j2.submit_time; " w% z4 {0 ~* R3 S } * t& C& T: ^( y3 e/ T }; $ ~6 o y& Y2 Y) W4 ^' R' v" T( m9 C. G' }) | G
FCFSSchedulingAlgorithm() 8 m) b1 `" B. C" F: I% y) @! d {} $ Z" @! k- o6 m - J" w7 \* q" V. u, oprivate:, s1 A* Y _. ]7 j3 [
! R% \) [; S8 x& m4 S$ k ) k4 q% b0 i0 _5 z9 D/ C};# W E# h, W! m! N% Y
j( [) W ?% {& i) n, ]9 [// Short Job First# a8 ~* E8 ?" F0 @
class SJFSchedulingAlgorithm : public SchedulingAlgorithm1 a3 M) b& O$ N' z5 W
{ 5 T8 L3 h" }7 C6 q y+ g7 Z2 Kpublic:. q4 G3 T- a/ N" p; T; w& K
struct PriorityCmp / w$ ^; D$ _6 K8 _( h5 f$ @5 x { ' g$ a1 ?- Z* M9 F: f4 i4 q bool operator()(const JCB j1, const JCB j2) $ K+ F5 s- @' k( y" j k" i# A {' g1 v+ P1 r* L8 ~3 g+ h, J
return j1.required_running_time > j2.required_running_time; , Z, y. }$ T* u } 5 r r4 {; Z2 R4 U- F };( n! I2 Z N! D0 q/ B3 z6 t
4 Z4 x4 D. F- z8 V0 g, {+ n
SJFSchedulingAlgorithm() ( A0 N1 c3 E9 t; k2 A3 s; k {}8 `6 ~$ o* o5 p& y
+ G: V9 n. Q% |% t7 ^};; l. B' w1 ], w$ {* [
; @9 Q# W F1 e, W5 m
// Highest Response Ratio Next - f( N K. a/ w8 k! {4 }$ K; eclass HRRNSchedulingAlgorithm : public SchedulingAlgorithm ) W) d* h- m* s' @0 n0 a) e{ 0 M* o5 ~# a3 [! n9 F& wpublic:7 b0 j# l; F6 Z1 D) `6 x* h7 j# a$ A
struct PriorityCmp 1 D$ @5 Z" h9 C) b- r { 4 h8 v. \) ^* R9 x) Q/ I double getPriority(JCB jcb) 3 t) G$ `0 b0 c; ?0 S( N {- s1 L5 v- x0 V5 Y0 E: V" P, K. q
return ((cur_time - jcb.submit_time) + jcb.required_running_time) / jcb.required_running_time; * i2 i" b. f; |$ p) a } ( b& f" g [. e8 d( Y7 f( c3 D6 Y9 R/ e9 m
bool operator()(const JCB j1, const JCB j2) # O& k F( Y' Z" s2 L. X) w5 _ { % I; l# r3 n% a, {, \$ V0 X4 d& U return getPriority(j1) > getPriority(j2);6 V# {! z1 e0 k1 F9 C
}' r6 ?" s/ X9 n, X) E6 D |( a5 w
}; 9 C2 q5 N; X* h5 R4 k( A0 Q+ T$ \3 s8 t
HRRNSchedulingAlgorithm()9 e- _# T; ^& \
{}+ X6 m, x U/ R
}; 8 I! L6 F+ H; ^$ K. Q4 c0 |4 Q; ]4 D: m+ }+ P
template<typename PriorityCmp>' O! u. z1 U1 L! r7 {3 ]1 g
class JobScheduling: C4 ~1 \- l4 V' D: B2 S# {4 q% J
{. }) Q; t& S7 f
public: & ]; Q+ W! j g* R# B2 L JobScheduling(int job_num), w' y2 G4 K$ @5 U
{ ; Q# }4 @5 ?: X2 e- }/ a$ k4 j job_num_ = job_num;5 A% O+ y& O6 u: x5 ^# [( X
sa_ = new SchedulingAlgorithm();" J+ w$ r$ Z) s% s+ S
wait_queue_ = new std::priority_queue<JCB, std::vector<JCB>, PriorityCmp>();, A' B" ]' ?% K @) O
mock_jcbs_ = new std::priority_queue<JCB, std::vector<JCB>, PriorityCmpForMock>(); . E/ ~& e, }/ J7 X. L" L# k1 r( C finish_queue_ = new std::queue<JCB>(); . S# B5 s" W V8 O8 ? 6 m. R+ O1 u. F, u) Y& ?! W mockJCBs(); ; |, W+ e) T2 C } W5 R! l9 G6 M4 \5 `+ ? . Q% H$ e1 b, vprotected: 9 t. y+ \ I# {8 c9 n# ^3 K struct PriorityCmpForMock + t# R/ K$ W6 P% {" z0 i; \3 ` { 0 S% c5 t0 R) S bool operator()(const JCB j1, const JCB j2): L$ z& O( \( g9 f% {+ Z7 H' r6 t
{ 7 t- }8 c: H1 P& | return j1.submit_time > j2.submit_time; ( N! x- j( [. K! R& D } # ]8 `! q2 Q' C9 V6 F };5 }& R' B7 w5 L2 C: ~% n
# X4 C. t& o, t; _, T& N" h+ V1 P bool mockJCBs() ) B% Q5 [8 c, Q6 ^8 s- N; {; @ {! x- c3 h) I' d9 |' U! }; Q
for (int i = 0; i < job_num_; ++i) 3 [! |+ H+ g" o# [7 t { 0 ^( z; H) Z( L5 |& D* u+ s JCBptr jcb = new JCB();. M; @- V# E' L- A1 q* P6 A5 N
jcb->job_name = "job" + std::to_string(i); 4 E) u% T8 [% l. g' e jcb->job_status = Wait;; [. z# J! C& C$ _7 S3 g) \ x5 b- K
jcb->submit_time = Util::getRandom(1, 20, i);" j* B/ O3 O) q
// The minimum value is 3 so that each segment can be divided into time slice 4 T5 b. r: T8 D jcb->required_running_time = Util::getRandom(3, 10, i); 0 L: [$ j$ { }6 ?1 T5 k0 _5 x$ t, W! S9 T
mock_jcbs_->push(*jcb); 9 O, H/ c0 z+ Y, t std::cout << "[INFO] finish init " << jcb->job_name << " with " & k% ^" S* W' y a0 {2 g. l- G& p << " submit_time " << jcb->submit_time ( \9 _ G% @5 ^9 \' T << " required_running_time " << jcb->required_running_time << std::endl; % g0 s, ~5 O) x" f0 ]3 c }6 k# Y$ y/ O, ?3 @ {) f5 y
} + ?9 B; E, Z U p+ l$ U d" t0 W# v- z7 l void getCurrentReadyQueue() 9 Q+ n" D @& d* O P( l. V {( n8 B& a7 m. ^7 [ f
while (!wait_queue_->empty()) 8 d2 U) O) E A4 T { ' a" f3 w( d: F! A; \ JCB jcb = wait_queue_->top();' a" c3 b6 B5 z- m
std::cout << jcb.submit_time << std::endl; 2 f. C: c* f& e wait_queue_->pop(); ' {, x0 ?* n2 X- n: D m l }6 s; T+ [) c# _$ i( m5 l4 n- c/ l
} . E: D( G2 t: v 6 K7 G+ v, `; ?$ m int job_num_; 7 l" P8 [2 F ^6 U! h3 z SchedulingAlgorithm* sa_;1 d1 I c0 K& Q6 l; O$ |. J! ^
std::priority_queue<JCB, std::vector<JCB>, PriorityCmpForMock>* mock_jcbs_; - b3 t& B8 e, m std::priority_queue<JCB, std::vector<JCB>, PriorityCmp>* wait_queue_;( v6 _- K1 {8 S4 v0 \
std::queue<JCB>* finish_queue_;) q0 V% \3 \& ]% z* a y6 c
};" j( N5 g: r0 a: _# E6 a
3 S& h' ]. H" w+ {
template<typename SchedulingAlgorithm, typename PriorityCmp> 5 ^! o6 i0 C7 |$ r4 |4 V( O! M0 bclass SimpleBatchProcessingSystemJobScheduling : JobScheduling<PriorityCmp>* ]' N; e2 c$ D+ K( c1 c; V. k; k
{ 5 i7 f5 x6 B5 B( u5 I# jpublic: + [3 ` E& A: s) z' I+ K SimpleBatchProcessingSystemJobScheduling(int job_num) & [. _, K! t2 t' M : JobScheduling<PriorityCmp>(job_num) 0 i" P1 U5 l- J5 \ {}2 [: ~+ p7 E4 U. Z
9 ?- V9 J! u3 }2 m bool start() * k5 z9 A/ B2 s% x, N% }# q0 t, F { - P4 ]: k+ L4 h& O cur_time = this->mock_jcbs_->top().submit_time; / u+ P) s9 J" o1 Z3 \ while (!this->wait_queue_->empty() || !this->mock_jcbs_->empty())* Q" ?+ f4 g. v# g# ^4 u
{ 8 A, y$ h7 S; A, A" b // Simulate adding tasks dynamically ! ]2 ~; A. e G, r$ i N if (!this->mock_jcbs_->empty() && this->mock_jcbs_->top().submit_time <= cur_time) 5 M2 i% v+ Y- O, S { # k( \; q' X H, T4 n JCB jcb = this->mock_jcbs_->top();- A+ N: j& y) J i: H
this->mock_jcbs_->pop(); / X% r/ c: g) M" M# c: S5 J ; q+ c, s5 k f1 O! T- V' { std::cout << "[INFO] add " << jcb.job_name << " to wait queue." << std::endl; 8 z: |* E4 n8 B this->wait_queue_->push(jcb);3 ?- R1 `0 f3 G8 ~, a
} ' m: A1 B# `) K/ f$ @# y3 i ; n) s- f1 d- N' q: ? if (!this->wait_queue_->empty()) + I+ I; l/ @; ?0 N& a {. q7 v# C: L2 k( [, I+ S- l
JCB jcb = this->wait_queue_->top();$ r6 |" @5 K1 w
this->wait_queue_->pop();! k7 h' D5 B" e9 w: R4 T$ W
: g, z& `% Y. ^" i" T9 i. Q6 g
std::cout << "[INFO] begin to do " << jcb.job_name << "." << std::endl;) S! g2 z& y" ^4 s7 E/ l
jcb.job_status = Run; 9 Z; w4 g7 H/ |6 l // simulation do job' H7 ?' C8 N$ P7 `% v3 ^
sleep(1); & e, x& o4 J5 u% F$ |9 j5 f std::cout << "[INFO] do " << jcb.job_name << " finish." << std::endl; 2 ~1 M' t8 o9 i: a7 t! S; X9 s, U% k" b! R5 m3 D: f
jcb.job_status = Finish; 9 S* u5 n5 D9 n, @ // print job Data.8 Z' u* p6 L( Y8 W6 d' E
Util::printJobData(jcb);+ _* ~# N& o3 i( s( v( c( P3 K. O
this->finish_queue_->push(jcb); . t0 X3 M! X; g3 K) { cur_time += jcb.required_running_time; ) k: Z$ ?3 W! ?4 |9 w } $ w( ?# C1 v+ y1 G( ` else + i# S( B( Z0 W% M8 F$ U5 a3 x {& K) M/ w5 X1 i: K0 ^1 u" i8 H" c
// Slowly increase time slice when there is no job2 V" m2 Y9 A8 r
cur_time += 1; / v& n3 c. R6 O( S% z- J }8 k7 T' y3 }; L. P: V
}4 h. [% d% _& N t. Z
std::cout << "[INFO] all jobs finished." << std::endl; . w: V/ i' c! ] @' Z std::cout << "[LOG] average turnaround time " << (average_turnaround_time / this->job_num_); z- B p1 e1 z R3 k
<< " average power turnaround time " << (average_power_turnaround_time / this->job_num_) << std::endl;- i/ _# t( `% o- U2 s; a/ r( m1 L1 i
}; o* q1 A+ `) ?7 E2 X! p
# c7 j/ j+ u7 d
private:+ l3 ?0 l% E4 ~
$ Y7 \( d% I* n2 o
};8 i. K, Q/ T5 u( H2 x2 a& ^* _) n
' Y% }" w. N& l, b: L9 _5 j6 v" I) Q$ U" P% n* {5 b
class MultiprogrammedBatchProcessingSystemJobScheduling9 ~; Y& \- ^! O2 [' I" S3 b
{ ) ~$ G4 F6 U i2 O4 tpublic: 2 h& c9 H4 j9 I struct PriorityCmpForPCB: z* f: }7 E5 M
{ ! w+ V( D+ l; o4 Q; g bool operator()(const PCBptr p1, const PCBptr p2) : C: @) j Q9 F1 ^# H5 f; N { 9 _. G5 J% p/ f3 g return p1->priority < p2->priority; . l; p: p( Z r } 7 a, U T) ] V0 _2 I1 i/ N };. p* P- m, G: B8 M
' m$ B3 e6 [& ]& k. R$ r8 W( M struct PriorityCmpForBack $ {1 h5 l0 Z% y- @7 j { , s$ E7 E8 S5 Z& I bool operator()(const JCBptr j1, const JCBptr j2)2 ]% g1 j3 I" A- s2 g
{% j6 r" I% p1 C; f- x
return j1->submit_time > j2->submit_time; 2 t* k# I. N' ?) a6 G8 O3 @ }) H" B6 i% P2 V
};3 T7 V2 _0 x6 W* ~, t2 b
: z/ w* P" k+ t/ g- a" S. P 3 v/ w% n: L% R- P8 W) i. D MultiprogrammedBatchProcessingSystemJobScheduling() 6 ~* U" }. P3 h {) V s0 ~' b6 @
back_queue_ = new std::priority_queue<JCBptr, std::vector<JCBptr>, PriorityCmpForBack>(); 4 @0 s1 U1 ^3 ? psa_ready_queue_ = new std::priority_queue<PCBptr, std::vector<PCBptr>, PriorityCmpForPCB>();, c+ N6 p p* P" o: k+ U. f
2 [4 C1 P0 A$ f" d% a, E- Y " m3 w5 c4 e% _2 j- H& p4 Z+ h std::cout << "input job num:" << std::endl; . N/ z) D, Q1 B' ]7 `& A std::cin >> job_num_; 2 o; ?# A" a* \/ @/ Q; ~ for (int i = 0; i < job_num_; i++) 7 \( N$ a) \- D4 U- c7 w {$ o0 ~5 `+ {, z' ^. ^% H
std::cout << "input job" << i << " submit_time & required_running_time & priority" << std::endl; , S' s+ T6 I+ |3 Z8 l9 {2 c) D ' z" P1 O6 K2 @$ l' r( i
JCBptr jcb = new JCB(); 6 l, z G) G3 Y+ P& Y( t jcb->job_name = "job" + std::to_string(i); 4 @ B$ H0 D- t* f jcb->job_status = Wait;0 K/ z) L. F! o, n- v- J% h
std::cin >> jcb->submit_time;& `# ]8 C& h6 k) P
std::cin >> jcb->required_running_time;6 {# S1 w( ?* x) I. h- m, e
std::cin >> jcb->pcb->priority; & [- I q' Q5 [" x1 |' i back_queue_->push(jcb); : I- v5 \' t/ n5 X$ s: b, _ } 1 J- z1 w3 x+ X' d* T " G2 V2 D# u/ w1 D" _0 h$ R /*. a' ~# [* m/ q8 F4 ^9 s! r8 N
job_num_ = 6; 4 A+ v4 s% q9 F- |- ^6 w' B9 i' v
JCBptr jcb = new JCB(); . m3 m) F' z' o; z- a jcb->job_name = "A";, ~/ n. w# @( g3 [+ ~
jcb->job_status = Wait; , O# S# u# X- `, m! P& { jcb->submit_time = 0;9 ]# z" R& \$ M4 W, \. R
jcb->required_running_time = 50; . I: {+ U/ H7 T" E jcb->pcb->priority = 5;% I6 L/ [6 Z3 s6 ]7 }
back_queue_->push(jcb); / a8 {5 v% Z: S! c1 ~! l1 d- C( Z# i: u) H. h9 B/ x
jcb = new JCB();" a: z( E u& L. q# c
jcb->job_name = "B"; & d% @2 f5 F. W# } jcb->job_status = Wait;; p9 A( B' V# n$ h
jcb->submit_time = 20;/ D- G2 C6 d0 `+ }/ I( _
jcb->required_running_time = 60; [) s, v% t. I2 x; y7 A y jcb->pcb->priority = 7;; j2 f* V2 g! R$ i: S( l
back_queue_->push(jcb);! F) t! [: P' @3 f( j
" n3 k- d: `5 t& \8 r jcb = new JCB();- s& _- {- D/ `; K8 f
jcb->job_name = "C"; 8 o q5 a3 \( I3 ` jcb->job_status = Wait;' C& p; E0 f1 \$ O& G5 A8 n& F
jcb->submit_time = 50; 9 O5 b8 _! C" _2 w1 R0 ~4 L$ R jcb->required_running_time = 40; " Y. a8 t) t8 Z, `* A3 I jcb->pcb->priority = 3;# y" l, k: S: T! M" Z2 V
back_queue_->push(jcb);6 V# F3 @4 y( j; l9 P
3 a, |, H, w, d- T* X6 { jcb = new JCB(); ; x$ m6 G# d2 K0 c jcb->job_name = "D"; + _) y- z+ K, \* Q jcb->job_status = Wait;1 ?% D6 n0 i0 Y$ G- X5 Z' h
jcb->submit_time = 80;5 y' \; | l# j7 R! C+ {
jcb->required_running_time = 80; % ~! w, v/ d' S& B/ x jcb->pcb->priority = 8; + U2 ^) s+ i2 y: D4 w back_queue_->push(jcb);$ O0 }7 v$ P& p" O; N) W0 m
# N* [3 n3 V) v! T jcb = new JCB(); 3 Q. x4 P# X. s: N J+ ~ m jcb->job_name = "E";. E K0 ^: A* @. |
jcb->job_status = Wait;* }6 k. Y# _3 Q: v
jcb->submit_time = 100; 5 t9 G* e# ~6 ~+ ]$ D) w; y jcb->required_running_time = 30;; j4 {2 Z/ |$ M8 `% w/ p- L+ i( n
jcb->pcb->priority = 6;. Q+ _2 S8 `5 B# }, }9 d
back_queue_->push(jcb);- W3 c z- q. V& u: p3 x1 b
- T2 h' [+ D* r& @3 `- }$ n! S
jcb = new JCB();1 j6 R5 D+ d5 x) |7 c
jcb->job_name = "F"; 4 \) r) m5 O( _7 H jcb->job_status = Wait; $ K) i9 V; Y2 }) m; o+ ` jcb->submit_time = 120;: l4 [2 u9 V2 J3 S5 V& P
jcb->required_running_time = 70; 3 v/ U: o% ~# O( B+ B jcb->pcb->priority = 9; v5 P0 I4 B0 n# b8 a back_queue_->push(jcb); S* l- ?. d( a */" G. |& R# \; p7 q$ G
} : ~$ v/ K+ c5 l 2 d2 h) y$ A- m: G2 T6 A bool start() ' _' m9 f z' \0 u3 d { 1 s# M' t* O1 t* z2 ^' N cur_time = back_queue_->top()->submit_time; / x" c/ k D2 O2 ? while (!back_queue_->empty() || !psa_ready_queue_->empty()), C& o1 t f% `
{ - Z3 j. k7 I+ b8 X3 b bool increase_time = true;: r1 g# H) @8 ?& l; i9 _8 ]) B
// Job FCFS/ p3 ~# R! X5 e& i! M! f% p
if(!back_queue_->empty() && psa_ready_queue_->size() < 2) , B: |6 d( z5 n {) v$ ` w! i8 C4 Y- U2 o
JCBptr jcb = back_queue_->top(); ; W" w$ H$ ^+ Y3 c/ _9 N$ ?: }$ t0 l if (jcb->submit_time <= cur_time) ( L" e, b) \/ v- Q. L# Y { - i' S1 u) f2 l+ q4 N back_queue_->pop();- z$ b# Z4 p/ Z
5 m+ I. m( J. v: `! V
// Process PSA: Q6 ~, N" l! X& p& k4 _
if (!psa_ready_queue_->empty()) ; o- V( A, Z- R2 Q) N% P! v! I { 6 e4 k% z+ r/ g% b' h( R2 ^) G) i% v PCBptr pcb = psa_ready_queue_->top(); & Y: E1 k1 I, q/ } JCBptr jcb = pcb->jcb; + Z- G, d1 @* z# }+ m. A3 p# ]8 k: S7 f
if (jcb->already_run_time >= jcb->required_running_time) 1 J3 }, s2 a1 v' x" s8 g {: Z2 ^9 J+ E$ _/ r3 b/ c8 c
jcb->job_status = Finish; S9 y: ^& [# k$ T( B; T6 f+ s" G
psa_ready_queue_->pop(); ! `8 \/ Z0 v* x/ i$ V) {6 g //std::cout << "[LOG]" << jcb->job_name << " Finish At " << cur_time << std::endl;# v4 H# m6 @9 M
9 X7 U( M' D3 n% j jcb->finish_time = cur_time;( O- p0 L' d) `- B+ j/ l
Util::printJobData(*jcb, true); N! t+ Z$ W' z% n. `% q+ U } 8 _0 B( z6 {. R* d7 z else* N& B8 F- B, V$ i6 ~
{" D1 ]/ \8 W8 [; V$ e
jcb->job_status = Wait; ( }5 @- M- }+ Q& M pcb->status = Ready; 3 @& ]5 H, U9 A' | //std::cout << "[LOG]" << jcb->job_name << " Ready At " << cur_time << std::endl;+ [( a; l ^" E3 F9 m; ]& X0 E
}! v% d3 J# H' I; k( t# Q4 \
}: ]# Q# I1 ~% T/ Z
# y, I$ C* _* u* I
psa_ready_queue_->push(jcb->pcb);0 |, ~3 @9 B- g- [
' R: o3 ~, q9 l/ Y
PCBptr pcb = psa_ready_queue_->top();$ [5 k/ P! c+ C a
JCBptr jcb = pcb->jcb;6 i9 y) Z* F# t( J
jcb->job_status = Run; # x+ F) M4 ^0 O4 n$ s$ } pcb->status = Running; 3 a m, z v8 _2 `. ~% }7 R . q, }5 C& w4 s# {' Q& j5 U1 Q //jcb->start_time = (jcb->start_time == -1) ? cur_time : jcb->start_time;% K1 }) Q+ K/ W) [ F+ \
//std::cout << "[LOG]" << jcb->job_name << " Begin Running At " << cur_time << std::endl;/ I: B# |1 W- k( Y4 ~7 g% j
( _! B) e& p# D5 L" D" n0 I6 m increase_time = false;, L3 K, O! L3 o, _
} 8 R0 a1 u9 o& S- ~1 G9 r } 1 c, F+ T, p0 }; s5 V3 z else if (!psa_ready_queue_->empty())8 f# R9 Q: d2 k; E1 q" k: H1 Y* U
{- V) G; W8 {, m: g, t; ~
PCBptr pcb = psa_ready_queue_->top(); ; f5 ^/ n l* M2 a2 P% ~) H JCBptr jcb = pcb->jcb; 3 Q/ e) ]+ \5 [ p+ }) C% H ; u. c# t) s" I6 w if (jcb->already_run_time >= jcb->required_running_time)" Z6 o& \3 t% P, J7 c# k" w
{ # u/ N" }) {, N" k) u+ f# L2 V jcb->job_status = Finish; 0 @% l9 n/ [6 u9 x% ^ psa_ready_queue_->pop();, r. q( h6 d& o) u/ P3 Y) M
//std::cout << "[LOG]" << jcb->job_name << " Finish At " << cur_time << std::endl;8 ?0 j2 F$ _/ R: {# W. D3 c( A
jcb->finish_time = cur_time; + u$ G1 m Q, r6 }8 o; M increase_time = false;! G$ E6 B9 G2 W/ s" c
' C7 I( y$ v) m3 i+ a0 @1 z- |
JCBptr jtop = psa_ready_queue_->top()->jcb;3 X! H* _; j& C, {9 ]
//jtop->start_time = (jtop->start_time == -1) ? cur_time : jtop->start_time;" W: B9 i5 ~, t: A6 [
Util::printJobData(*jcb, true); 4 B' E5 a: {! v3 y8 [* Q/ Z Y: |' {8 Q }2 L1 W! A9 G* m; Z# V
} + }. u+ d* [, A6 F. c/ U. Y ; D w& h. ^& J
if (increase_time) 3 \6 @+ S* t% `% ~6 ~4 T { ; H; U# J# B- u1 L3 M if (!psa_ready_queue_->empty()) " a3 c/ n l, l% u {2 n1 P- L, U1 g+ g: F. x+ h6 ^
PCBptr pcb = psa_ready_queue_->top(); / _! i1 a/ M' K9 e @ pcb->jcb->already_run_time++; ! ^$ G1 G d& {$ {, K }' n* A2 x0 Y3 c" H- W9 X- T9 n
cur_time++;# s2 S- a. c# Z- ?
} 0 i+ ^/ |1 `9 A' [ b }/ u& E" `8 J2 G% ^* n- ^
std::cout << "[INFO] all jobs finished." << std::endl; , V, S4 M0 H- d8 O, E1 L std::cout << "[LOG] average turnaround time " << (average_turnaround_time / job_num_) 2 ?. B" ^& G0 j) L, x << " average power turnaround time " << (average_power_turnaround_time / job_num_) << std::endl; * ~9 I( p- }$ @& O* R( w }% k7 b9 N7 M3 Y. Y2 T
+ ^* J8 A* M! N( r' L8 fprivate:; }& ]( m2 h/ G
int job_num_; 3 a" l9 u) H5 H3 z& i. d( G$ y) l std::priority_queue<JCBptr, std::vector<JCBptr>, PriorityCmpForBack>* back_queue_; $ u' ~; {( w( R( A" k$ } std::priority_queue<PCBptr, std::vector<PCBptr>, PriorityCmpForPCB>* psa_ready_queue_; 1 l6 ?+ f9 z, x}; * I, E5 @$ ]0 B' c g- }6 |3 n 8 j! L$ o# L( B& S- u9 w/* 2 v6 v& I* f/ D& { zint main(), e% w, |5 }2 B8 U# h/ i! X
{ 6 |% w1 p0 ^' L4 \! x8 V5 l( }6 D SimpleBatchProcessingSystemJobScheduling<FCFSSchedulingAlgorithm> js(4); - w: A6 i: M; y e' v% N/ v js.getCurrentReadyQueue(); ) k- |/ m" a' \+ b: c * u: P8 H4 Q, d6 q8 l% }( O // pause to see result ; A3 i- l( S, n5 j3 H$ U$ k getchar();1 g/ s1 ]% }2 @# F
return 0; 6 g0 {7 T* x1 L8 g+ J}" E, |8 a4 T6 @. {* R7 Z" W9 ?$ d
*/( A- s. _ X# O) G0 p1 m% C
& t; G7 R: {2 C2 Y2 X
六、运行结果# j# b! f# G+ b, G* y
6.1 单道批处理(FCFS) , g, E; b9 ~% ?9 ~' Z8 O" G% T) y ' @; R3 O+ g- g 2 ~% C U, Y9 Y. ^6.2 单道批处理(SJF) ! j$ ?* N1 t p7 u& @! A + a, Q. R% @# W$ Q4 B' \' I+ `; |& {: c& y' q8 a. Y
6.3 单道批处理(HRRN)9 u9 Y$ A( {, d& v- r. ^! h! w# R _
- Y, Z6 V. p d ' W6 Q2 q/ ]3 F- c6.4 多道批处理(FCFS + PSA)! ?" r) j. J/ D8 w0 s; ]
, Q. [* H' w7 b6 x" F5 Y. R! T1 ]
5 i3 q4 b \$ ^' L
七、结尾 ' x% x- b/ S: {, P 如果本文描述的内容或使用的代码存在任何问题,请及时联系我或在本篇文章的下面进行评论,我会本着对每一位学技术同学的负责态度立即修改。在后续还会有三篇计算机操作系统的算法 C++ 复现博文,如果感兴趣可以关注我。/ c9 {7 S+ ]8 F# _
————————————————+ v$ k9 {( G5 J+ n! B6 C, f
版权声明:本文为CSDN博主「杨小帆_」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 ' g( w4 A4 l! {6 R. t原文链接:https://blog.csdn.net/qq_40697071/article/details/106698130& v! T( H, G$ P. r