From c4e7dbd9105a0765ee359a851f3cd676a0373fd0 Mon Sep 17 00:00:00 2001 From: yuchen Date: Tue, 7 Apr 2015 10:21:28 +0800 Subject: [PATCH] add process-concept spoc homework --- related_info/lab4/process-concept-homework.md | 83 ++++++++ related_info/lab4/process-concept-homework.py | 195 ++++++++++++++++++ 2 files changed, 278 insertions(+) create mode 100644 related_info/lab4/process-concept-homework.md create mode 100755 related_info/lab4/process-concept-homework.py diff --git a/related_info/lab4/process-concept-homework.md b/related_info/lab4/process-concept-homework.md new file mode 100644 index 0000000..92fbdf9 --- /dev/null +++ b/related_info/lab4/process-concept-homework.md @@ -0,0 +1,83 @@ +设计一个简化的进程管理子系统,可以管理并调度如下简化进程.给出了参考代码 + +### 进程的状态 + + - RUNNING - 进程正在使用CPU + - READY - 进程可使用CPU + - DONE - 进程结束 + +### 进程的行为 + - 使用CPU, + - 发出YIELD请求,放弃使用CPU + + +### 进程调度 + - 使用FIFO/FCFS:先来先服务 + +### 关键模拟变量 + - 进程列表:描述了进程的行为特征:(1)使用CPU ;(2)等待I/O +``` + -l PROCESS_LIST, --processlist= X1:Y1,X2:Y2,... + X 是进程的执行指令数; + Y是执行CPU的比例(0..100) ,如果是100,表示不会发出yield操作 +``` + - 进程切换行为:系统决定何时(when)切换进程:进程结束或进程发出yield请求 + + +### 执行实例 + +#### 例1 +``` +$./process-simulation.py -l 5:50 +Process 0 + yld + yld + cpu + cpu + yld + +Important behaviors: + System will switch when the current process is FINISHED or ISSUES AN YIELD +Time PID: 0 + 1 RUN:yld + 2 RUN:yld + 3 RUN:cpu + 4 RUN:cpu + 5 RUN:yld + +``` + + +#### 例2 +``` +$./process-simulation.py -l 5:50,5:50 +Produce a trace of what would happen when you run these processes: +Process 0 + yld + yld + cpu + cpu + yld + +Process 1 + cpu + yld + cpu + cpu + yld + +Important behaviors: + System will switch when the current process is FINISHED or ISSUES AN YIELD +Time PID: 0 PID: 1 + 1 RUN:yld READY + 2 READY RUN:cpu + 3 READY RUN:yld + 4 RUN:yld READY + 5 READY RUN:cpu + 6 READY RUN:cpu + 7 READY RUN:yld + 8 RUN:cpu READY + 9 RUN:cpu READY + 10 RUN:yld READY + 11 RUNNING DONE +``` diff --git a/related_info/lab4/process-concept-homework.py b/related_info/lab4/process-concept-homework.py new file mode 100755 index 0000000..a03f6e0 --- /dev/null +++ b/related_info/lab4/process-concept-homework.py @@ -0,0 +1,195 @@ +#! /usr/bin/env python + +import sys +from optparse import OptionParser +import random + +# process states +STATE_RUNNING = 'RUNNING' +STATE_READY = 'READY' +STATE_DONE = 'DONE' + +# members of process structure +PROC_CODE = 'code_' +PROC_PC = 'pc_' +PROC_ID = 'pid_' +PROC_STATE = 'proc_state_' + +# things a process can do +DO_COMPUTE = 'cpu' +DO_YIELD = 'yld' + + +class scheduler: + def __init__(self): + # keep set of instructions for each of the processes + self.proc_info = {} + return + + def new_process(self): + proc_id = len(self.proc_info) + self.proc_info[proc_id] = {} + self.proc_info[proc_id][PROC_PC] = 0 + self.proc_info[proc_id][PROC_ID] = proc_id + self.proc_info[proc_id][PROC_CODE] = [] + self.proc_info[proc_id][PROC_STATE] = STATE_READY + return proc_id + + def load(self, program_description): + proc_id = self.new_process() + tmp = program_description.split(':') + if len(tmp) != 2: + print 'Bad description (%s): Must be number ' + print ' where X is the number of instructions' + print ' and Y is the percent change that an instruction is CPU not YIELD' + exit(1) + + num_instructions, chance_cpu = int(tmp[0]), float(tmp[1])/100.0 + for i in range(num_instructions): + if random.random() < chance_cpu: + self.proc_info[proc_id][PROC_CODE].append(DO_COMPUTE) + else: + self.proc_info[proc_id][PROC_CODE].append(DO_YIELD) + return + + #change to READY STATE, the current proc's state should be expected + #if pid==-1, then pid=self.curr_proc + def move_to_ready(self, expected, pid=-1): + #YOUR CODE + return + + #change to RUNNING STATE, the current proc's state should be expected + def move_to_running(self, expected): + #YOUR CODE + return + + #change to DONE STATE, the current proc's state should be expected + def move_to_done(self, expected): + #YOUR CODE + return + + #choose next proc using FIFO/FCFS scheduling, If pid==-1, then pid=self.curr_proc + def next_proc(self, pid=-1): + #YOUR CODE + return + + def get_num_processes(self): + return len(self.proc_info) + + def get_num_instructions(self, pid): + return len(self.proc_info[pid][PROC_CODE]) + + def get_instruction(self, pid, index): + return self.proc_info[pid][PROC_CODE][index] + + def get_num_active(self): + num_active = 0 + for pid in range(len(self.proc_info)): + if self.proc_info[pid][PROC_STATE] != STATE_DONE: + num_active += 1 + return num_active + + def get_num_runnable(self): + num_active = 0 + for pid in range(len(self.proc_info)): + if self.proc_info[pid][PROC_STATE] == STATE_READY or \ + self.proc_info[pid][PROC_STATE] == STATE_RUNNING: + num_active += 1 + return num_active + + def space(self, num_columns): + for i in range(num_columns): + print '%10s' % ' ', + + def check_if_done(self): + if len(self.proc_info[self.curr_proc][PROC_CODE]) == 0: + if self.proc_info[self.curr_proc][PROC_STATE] == STATE_RUNNING: + self.move_to_done(STATE_RUNNING) + self.next_proc() + return + + def run(self): + clock_tick = 0 + + if len(self.proc_info) == 0: + return + + # make first one active + self.curr_proc = 0 + self.move_to_running(STATE_READY) + + # OUTPUT: heade`[rs for each column + print '%s' % 'Time', + for pid in range(len(self.proc_info)): + print '%10s' % ('PID:%2d' % (pid)), + + print '' + + # init statistics + cpu_busy = 0 + + while self.get_num_active() > 0: + clock_tick += 1 + + # if current proc is RUNNING and has an instruction, execute it + # statistics clock_tick + instruction_to_execute = '' + if self.proc_info[self.curr_proc][PROC_STATE] == STATE_RUNNING and \ + len(self.proc_info[self.curr_proc][PROC_CODE]) > 0: + #YOUR CODE + + # OUTPUT: print what everyone is up to + print '%3d ' % clock_tick, + for pid in range(len(self.proc_info)): + if pid == self.curr_proc and instruction_to_execute != '': + print '%10s' % ('RUN:'+instruction_to_execute), + else: + print '%10s' % (self.proc_info[pid][PROC_STATE]), + + print '' + + # if this is an YIELD instruction, switch to ready state + # and add an io completion in the future + if instruction_to_execute == DO_YIELD: + #YOUR CODE + + # ENDCASE: check if currently running thing is out of instructions + self.check_if_done() + return (clock_tick) + +# +# PARSE ARGUMENTS +# + +parser = OptionParser() +parser.add_option('-s', '--seed', default=0, help='the random seed', action='store', type='int', dest='seed') +parser.add_option('-l', '--processlist', default='', + help='a comma-separated list of processes to run, in the form X1:Y1,X2:Y2,... where X is the number of instructions that process should run, and Y the chances (from 0 to 100) that an instruction will use the CPU or issue an YIELD', + action='store', type='string', dest='process_list') +parser.add_option('-p', '--printstats', help='print statistics at end; only useful with -c flag (otherwise stats are not printed)', action='store_true', default=False, dest='print_stats') +(options, args) = parser.parse_args() + +random.seed(options.seed) + +s = scheduler() + +# example process description (10:100,10:100) +for p in options.process_list.split(','): + s.load(p) + + +print 'Produce a trace of what would happen when you run these processes:' +for pid in range(s.get_num_processes()): + print 'Process %d' % pid + for inst in range(s.get_num_instructions(pid)): + print ' %s' % s.get_instruction(pid, inst) + print '' +print 'Important behaviors:' +print ' System will switch when the current process is FINISHED or ISSUES AN YIELD' + +(clock_tick) = s.run() + +if options.print_stats: + print '' + print 'Stats: Total Time %d' % clock_tick + print ''