【操作系统】用c++实现简单的进程调度程序
来源:互联网 发布:js escape的用法 编辑:程序博客网 时间:2024/05/29 01:54
模拟linux实现了基本的资源仓库、进程池、资源申请、资源释放、创建进程、进程调度(多级反馈调度)、进程撤销、时间中断和一个简单的脚本。一个课程实验,很多bug、不完善,只是为了模拟进程调度算法,所以不是真实的申请资源(资源也是模拟的),甚至可以说是just for fun吧,将就着看。个人觉得,这种程序自己写一遍可以加深印象,但不要强求完善,这不是一朝一夕的事,也没有必要,要知道linux的进程调度也不是很完善哦。将四个文件放到同一目录下运行。
data.h
#include <stdio.h>#include <iostream>#include <map>#include <queue>#include <list>#include <vector>#include <string>#include <fstream>#include <time.h>#include <Windows.h>#define DEBUG#define __UNSAFE__#define NO_PROCESS_IS_RUNNING 0x7fffffff//进程资源获取状态#define OBTAINED_ALL_RESOURCE 1#define SYSTEM_RESOURCE_NOT_ENOUGH 0#define RESOURCE_NOT_ENOUGH_TEMP 2//资源数目#define n0 10#define n1 10#define n2 10#define n3 10using namespace std;//process statusenum p_st{ ready = 0, running, blocked };string getProcessStatusString(p_st st);//resource typeenum r_ty{ R0 = 0, R1, R2, R3 };string getResourceTypeName(r_ty ty);r_ty getTypeByStr(string str);//资源typedef struct { string r_id; //resource id bool r_st; //resource status,0 free,1 used r_ty type; //可以定义资源动作}resource;////请求的资源数目和实例typedef struct{ int num; r_ty type; //加这个属性的目的是释放资源时要通过该属性来从资源仓库中查找到对应的RCB修改剩余数目 list<resource * > occupied;}need;//进程控制块class PCB{public: PCB(PCB *Parent,string nm, int Prio, map<r_ty, need *> need) : parent(Parent), name(nm),priority(Prio), other_resource(need){ p_status = p_st::ready; } PCB(){} //因为懒写setter和getter所以就public了public: unsigned int process_id; string name; map<r_ty, need *> other_resource; //进程需要的资源类型及数目 bool getAllResource=0; p_st p_status; //进程状态 int queue_now; //当前所在的队列,0,1,2为就绪队列,3为阻塞队列,4表示不在任何队列,running状态 PCB *parent; //进程树中的父节点 PCB *child; //进程树中的子节点 int priority; //进程优先级};//资源控制块class RCB{public: RCB(r_ty type, int n) :ty(type), sum(n){ this->remain = n; resource *r = new resource[n]; for (int i = 0; i < n; i++){ r[i].r_id = getResourceTypeName(type) + to_string(i); r[i].r_st = 0; r[i].type = type; res.push_back(r[i]); } delete[] r; } RCB(){}public: r_ty ty; //resource type int sum; //sum of resource int remain; //remainder resource vector<resource> res; queue<int> w_queue; //resource waiting queue};//资源仓库static map<r_ty, RCB*> storage;//进程池static map<int, PCB*> process_pool;//就绪队列static queue<int> ready_queue0;static queue<int> ready_queue1;static queue<int> ready_queue2;//阻塞队列static map<int,int> blocked_queue;//运行进程static int running_process = NO_PROCESS_IS_RUNNING;//日志文件static fstream f;//注册资源RCBvoid register_resource(r_ty type,RCB *r);//定义资源void defineResource();//获取资源RCBRCB *getRCBbyType(r_ty type);//从进程池获取进程PCBPCB *getPCBbyId(int id);////从进程池中删除PCB//void deletePCB(int id);//获取不重复最小idint getValidResourceId();//写日志void LOG(string str);//资源申请int request(int process_id);//释放资源void release(int process_id);//创建进程PCB *create(PCB *Parent, int Prio, map<r_ty, need *> Need, string pn);//进程调度void scheduler();//进程撤销void destroy( int process_id);void run(PCB *pcb);void init();//定时器中断void timeOut();//驱动程序void showMenu();void testShell();void showAllResource();void showAllProcess();
data.cpp
#include"data.h"string getProcessStatusString(p_st st){ switch (st){ case 0:return "ready";break; case 1:return "running";break; case 2:return "blocked";break; default:return "NULL";break; }}string getResourceTypeName(r_ty ty){ switch (ty){ case R0:return "r0";break; case R1:return "r1";break; case R2:return "r2";break; case R3:return "r3";break; default:return "NULL";break; }}r_ty getTypeByStr(string str){ if (str == "R0") return r_ty::R0; else if (str == "R1") return r_ty::R1; else if (str == "R2") return r_ty::R2; else if (str == "R3") return r_ty::R3;}//注册资源RCBvoid register_resource(r_ty type, RCB *r){ storage[type] = r;}//定义资源void defineResource(){ //定义资源 RCB *r0 = new RCB(r_ty::R0, n0); RCB *r1 = new RCB(r_ty::R1, n1); RCB *r2 = new RCB(r_ty::R2, n2); RCB *r3 = new RCB(r_ty::R3, n3); //for (int i = 0; i < 3; i++){ // cout << r0->res[i].r_id <<" "<< r0->res[i].type<<endl; //} register_resource(r_ty::R0, r0); register_resource(r_ty::R1, r1); register_resource(r_ty::R2, r2); register_resource(r_ty::R3, r3);}//获取资源RCBRCB *getRCBbyType(r_ty type){ auto it = storage.find(type); return it->second;}//获取进程PCBPCB *getPCBbyId(int id){ auto it = process_pool.find(id); if (it != process_pool.end()) return it->second; else return nullptr;}//获取不重复最小idint getValidId(){ for (int i = 0; 1; i++){ if (process_pool.find(i) == process_pool.end()) return i; }}//写日志void LOG(string str){ f.open("LOG.txt", ios::out | ios::ate | ios::app); time_t t = time(NULL); struct tm* Time = localtime(&t); //mark 重定向到文件之后写文件不完整 cout<< Time->tm_mon + 1 << "-" << Time->tm_mday << " " << Time->tm_hour << ":" << Time->tm_min << ":" << Time->tm_sec <<" "<< str << endl;}void run(PCB *it){ it->p_status = p_st::running; running_process = it->process_id; //LOG("LOG: @run," + it->name + " is running..."); //mark 这里需不需要调度 //scheduler();}void init(){ map<r_ty, need *> rr; create(nullptr, 0, rr, "init"); PCB *init = getPCBbyId(0); init->p_status = p_st::running; LOG("LOG: @init,init is running..."); init->getAllResource = 1; running_process = init->process_id;}//定时器中断void timeOut(){ PCB *it = getPCBbyId(running_process); if (it == nullptr){ //运行中的进程未找到,这不太可能发生,因为至少还有一个init虚拟进程 LOG("LOG: @time_out, PCB not found when try to found running_process,it may happened when the ready queue is empty."); return; //mark warning,可以不处理 } else{ switch (it->queue_now){ case 0: if (!ready_queue0.empty()&&ready_queue0.front()==it->process_id) ready_queue0.pop(); break; case 1: if (!ready_queue1.empty() && ready_queue1.front() == it->process_id) ready_queue1.pop(); break; case 2: if (!ready_queue2.empty() && ready_queue2.front() == it->process_id) ready_queue2.pop(); break; } it->p_status = p_st::ready; if (it->queue_now == 0); else if (it->queue_now > 0){ it->queue_now--; } else{ LOG("LOG: @timeOut,fatal error:queue_now < 0"); } } //将中断的进程id入优先级对应的就绪队列 LOG("LOG: @timeOut," + it->name + " timeout, enter ready queue " + to_string(it->queue_now) + " ,priority is " + to_string(it->priority)); switch (it->queue_now){ case 0: ready_queue0.push(it->process_id); break; case 1: ready_queue1.push(it->process_id); break; case 2: ready_queue2.push(it->process_id); break; } //唤醒最高优先级的进程,循环查找三个就绪队列,直到找到非空进程为止,并为之申请资源 bool get2 = false, get1 = false; PCB *pcb = nullptr; //遍历ready_queue2 while (1){ if (ready_queue2.empty()) break; else{ if (pcb = getPCBbyId(ready_queue2.front())){ if (request(pcb->process_id) == OBTAINED_ALL_RESOURCE){ get2 = true; break; } else if (request(pcb->process_id) == SYSTEM_RESOURCE_NOT_ENOUGH){ //mark 当系统资源不足时,这里处理完了没有? //销毁pcb,出就绪队列2,获取下一个进程。 //destroy(pcb->process_id)-----已经在request里面销毁了 LOG("LOG: @timeOut,when erdogic reasdy_queue2,one process has been destroied because system resource can not satisfy it!"); //ready_queue2.pop(); continue; } else if (request(pcb->process_id) == RESOURCE_NOT_ENOUGH_TEMP){ LOG("LOG: @timeOut," + pcb->name + "been blocked when request resource!"); continue; } } //获取到的pcb为空的话 else{ ready_queue2.pop(); continue; } } } //遍历ready_queue1 while (1){ if (get2 || ready_queue1.empty()) break; else if (pcb = getPCBbyId(ready_queue1.front())){ if (request(pcb->process_id) == OBTAINED_ALL_RESOURCE){ get1 = true; break; } else if (request(pcb->process_id) == SYSTEM_RESOURCE_NOT_ENOUGH){ //mark 当系统资源不足时,这里处理完了没有? //销毁pcb,出就绪队列1,获取下一个进程。 //destroy(pcb->process_id)-----已经在request里面销毁了 LOG("LOG: @timeOut,when erdogic ready_queue1,one process has been destroied because system resource can not satisfy it!"); //ready_queue1.pop(); continue; } else if (request(pcb->process_id) == RESOURCE_NOT_ENOUGH_TEMP){ LOG("LOG: @timeOut," + pcb->name + "been blocked when request resource!"); continue; } } //获取pcb为空时 else{ ready_queue1.pop(); continue; } } //遍历ready_queue0 while (1){ if (get2 || get1) break; else if (pcb = getPCBbyId(ready_queue0.front())){ if (request(pcb->process_id) == OBTAINED_ALL_RESOURCE){ break; } else if (request(pcb->process_id) == SYSTEM_RESOURCE_NOT_ENOUGH){ //mark 当系统资源不足时,这里处理完了没有? //销毁pcb,出就绪队列0,获取下一个进程。 //destroy(pcb->process_id)-----已经在request里面销毁了 LOG("LOG: @timeOut,when erdogic reasdy_queue0,one process has been destroied because system resource can not satisfy it!"); //ready_queue0.pop(); continue; } else if (request(pcb->process_id) == RESOURCE_NOT_ENOUGH_TEMP){ LOG("LOG: @timeOut," + pcb->name + "been blocked when request resource!"); continue; } } else{ //因为init不会被阻塞,所以这种情况不可能出现) LOG("LOG: @timeOut,all ready queue is empty,timeOut return."); return; } } //运行 run(pcb); LOG("LOG: @timeOut," + pcb->name + " is running......"); scheduler();}//资源申请int request(int process_id){ //所需资源数 PCB *it= getPCBbyId(process_id); if (it == nullptr){ LOG("LOG: @request,PCB not found ,when try to found process which is requesting resources,the process may have been destroied."); } //如果进程已经获取了所有资源的话 else if (it->getAllResource) return OBTAINED_ALL_RESOURCE; else{ map<r_ty, need *>::iterator iter; for (iter = it->other_resource.begin(); iter != it->other_resource.end(); iter++){ int n = iter->second->num; RCB *rcb = getRCBbyType(iter->second->type); LOG("LOG: @request, " + it->name + " is requesting " + to_string(iter->second->num) + " resources " + getResourceTypeName(rcb->ty)); //如果进程所需资源数大于资源总数,释放已经获取的资源,销毁进程 //出就绪队列 if (n > rcb->sum){ LOG("LOG: @request,system Resource Not Enough,when " + it->name + " request resource " + getResourceTypeName(rcb->ty)); switch (it->queue_now){ case 0: if (!ready_queue0.empty()) ready_queue0.pop(); break; case 1: if (!ready_queue1.empty()) ready_queue1.pop(); break; case 2: if (!ready_queue2.empty()) ready_queue2.pop(); break; } release(process_id); destroy(process_id); return SYSTEM_RESOURCE_NOT_ENOUGH; } //如果资源足够,则遍历该类资源仓库,修改n个资源的状态并将资源交给进程 else if (n <= rcb->remain){ rcb->remain -= n; //遍历各类资源线性表,找到n个空闲资源分配给进程 int j = 0; //log string logStr = it->name + " get resource :"; for (vector<resource>::iterator i = rcb->res.begin(); i != rcb->res.end(); i++){ //若资源状态为非空闲 if (i->r_st == 1){ continue; } else{ j++; i->r_st = 1; //将空闲资源分配给进程 //mark bug iter->second->occupied.push_back(&(*i)); //mark logStr += i->r_id + " "; } if (j == n) break; } //mark LOG("LOG: @request,"+logStr); } //如果资源不够,则阻塞进程 else if (n > rcb->remain){ //cout << "当资源不够时:"<< endl; release(it->process_id); //释放已获取的资源 it->p_status = p_st::blocked; //修改进程状态为blocked LOG("LOG: @request," + it->name + " is blocked by " + getResourceTypeName(rcb->ty)); switch (it->queue_now){ case 0: if (!ready_queue0.empty()) ready_queue0.pop(); break; case 1: if (!ready_queue1.empty()) ready_queue1.pop(); break; case 2: if (!ready_queue2.empty()) ready_queue2.pop(); break; } //////mark error it->queue_now = 3; blocked_queue[it->process_id] = it->process_id;//入阻塞队列 storage[iter->second->type]->w_queue.push(it->process_id); //入该资源的等待队列 scheduler(); return RESOURCE_NOT_ENOUGH_TEMP; } } it->getAllResource = true; } return OBTAINED_ALL_RESOURCE;}//释放资源void release(int process_id){ PCB *pcb = getPCBbyId(process_id); if (pcb == nullptr){ LOG("LOG: @release, PCB not found ,when try to found process which is releaseing resources,the process may have been destroied."); } map<r_ty, need *>::iterator it; for (it = pcb->other_resource.begin(); it != pcb->other_resource.end(); it++){ //将进程中的资源返还,资源剩余数增加,资源状态修改为空闲 RCB *rcb = getRCBbyType(it->first); rcb->remain += it->second->num; for (list<resource *>::iterator i = it->second->occupied.begin(); i != it->second->occupied.end(); i++){ (*i)->r_st = 0; } //清空申请到的资源列表 it->second->occupied.clear(); //激活资源等待队列中队头的进程 PCB *temp; while (!rcb->w_queue.empty()){ temp = getPCBbyId(rcb->w_queue.front()); if (temp == nullptr){ LOG("LOG: @release, PCB not found ,when try to found the front process of blocked_queue,the process may have been destroied."); //cout << "the front process of ready_queue2 is not found!!!" << endl; rcb->w_queue.pop(); continue; } else{ temp->p_status = p_st::ready; temp->queue_now = temp->priority; //出阻塞队列 //blocked_queue.erase[temp->process_id]; LOG("LOG: @release, " + temp->name + " is activated by " + getResourceTypeName(it->first)); switch (temp->queue_now){ case 0: ready_queue0.push(temp->process_id); break; case 1: ready_queue1.push(temp->process_id); break; case 2: ready_queue2.push(temp->process_id); break; } //mark scheduler() scheduler(); break; } } } //调用调度函数 scheduler();}//创建进程PCB *create(PCB *Parent, int Prio, map<r_ty, need *> Need, string pn){ PCB *pcb = new PCB(Parent,pn, Prio, Need); pcb->queue_now = Prio; pcb->process_id = getValidId(); LOG("LOG: @create,create process " + pcb->name + " with priority " + to_string(pcb->priority)); //将进程添加到进程池 process_pool[pcb->process_id] = pcb; //入就绪队列 LOG("LOG: @create," + pcb->name + " enter ready_queue" + to_string(pcb->priority)); switch (pcb->queue_now){ case 0: ready_queue0.push(pcb->process_id); break; case 1: ready_queue1.push(pcb->process_id); break; case 2: ready_queue2.push(pcb->process_id); break; } //调用调度函数 scheduler(); return pcb;}//进程撤销void destroy(int process_id){ PCB *pcb=getPCBbyId(process_id); if (pcb == nullptr){ LOG("LOG: @destroy, PCB not found!"); return; } string logStr = "LOG: @destroy," + pcb->name + " is been destroied!"; delete pcb; process_pool.erase(process_id); LOG(logStr);}//进程调度void scheduler(){ LOG("LOG: @scheduler,system is scheduling......"); if (running_process != NO_PROCESS_IS_RUNNING){ PCB *pcbRuning = getPCBbyId(running_process); if (pcbRuning == nullptr){ LOG("LOG: @scheduler,PCB not found,when try to found the running process,the process may have been destroied."); } PCB *pcb; bool queue2_get = false; while (!ready_queue2.empty()){ pcb = getPCBbyId(ready_queue2.front()); if (pcb == nullptr){ LOG("LOG: @scheduler,PCB not found,when try to found the front process of ready_queue2,the process may have been destroied."); ready_queue2.pop(); continue; } else if (pcb->priority > pcbRuning->priority){ pcbRuning->p_status = p_st::ready; switch (pcbRuning->queue_now){ case 0: ready_queue0.push(running_process); break; case 1: ready_queue1.push(running_process); break; case 2: ready_queue2.push(running_process); break; } //marks_sheduler_resuest if (request(pcb->process_id) == OBTAINED_ALL_RESOURCE){ run(pcb); LOG("LOG: @scheduler," + pcb->name + " is running......"); ready_queue2.pop(); LOG("LOG: @scheduler, " + pcbRuning->name + " is grabed by " + pcb->name); //cout << pcb->name << " is running......" << endl; queue2_get = true; break; } else if (request(pcb->process_id) == SYSTEM_RESOURCE_NOT_ENOUGH){ //mark 当系统资源不足时,这里处理完了没有? //销毁pcb,出就绪队列1,获取下一个进程。 //destroy(pcb->process_id)-----已经在request里面销毁了 LOG("LOG: @scheduler,when request resource for a activate process in ready_queue2,one process has been destroied because system resource can not satisfy it!"); //ready_queue1.pop(); continue; } else if (request(pcb->process_id) == RESOURCE_NOT_ENOUGH_TEMP){ LOG("LOG: @scheduler," + pcb->name + "been blocked when request resource!"); continue; } } else break; } bool queue1_get = false; while (!queue2_get&&!ready_queue1.empty()) { PCB *pcb = getPCBbyId(ready_queue1.front()); if (pcb == nullptr){ LOG("LOG: @scheduler,PCB not found,when try to found the front process of ready_queue1,the process may have been destroied."); ready_queue1.pop(); continue; } else if (pcb->priority > pcbRuning->priority){ pcbRuning->p_status = p_st::ready; switch (pcbRuning->queue_now){ case 0: ready_queue0.push(running_process); break; case 1: ready_queue1.push(running_process); break; case 2: ready_queue2.push(running_process); break; } //请求资源并运行 if (request(pcb->process_id) == OBTAINED_ALL_RESOURCE){ run(pcb); LOG("LOG: @scheduler," + pcb->name + " is running......"); ready_queue1.pop(); LOG("LOG: @scheduler, " + pcbRuning->name + " is grabed by " + pcb->name); break; } else if (request(pcb->process_id) == SYSTEM_RESOURCE_NOT_ENOUGH){ //mark 当系统资源不足时,这里处理完了没有? //销毁pcb,出就绪队列1,获取下一个进程。 //destroy(pcb->process_id)-----已经在request里面销毁了 LOG("LOG: @scheduler,when request resource for a activate process in ready_queue2,one process has been destroied because system resource can not satisfy it!"); //ready_queue1.pop(); continue; } else if (request(pcb->process_id) == RESOURCE_NOT_ENOUGH_TEMP){ LOG("LOG: @scheduler," + pcb->name + "been blocked when request resource!"); continue; } } else break; } }}void showMenu(){ cout << "\n+------------------------help------------------------+" << endl; cout << "please init and open shell file first." << endl; cout << " |-->help: |" << endl; cout << " | help/-help/--help/man |" << endl; cout << " |-->init task management procedure: |" << endl; cout << " | init |" << endl; cout << " |-->open shell file: |" << endl; cout << " | [filename] |" << endl; cout << " |-->create process: |" << endl; cout << " | cr [process name] [priority] |" << endl; cout << " |-->timeout running process: |" << endl; cout << " | to |" << endl; cout << " |-->show all resource or process: |" << endl; cout << " | show [ar/ap] |" << endl; cout << " |-->show real-time scheduler: |" << endl; cout << " | top |" << endl; cout << "+----------------------------------------------------+"<<endl; cout << endl;}//驱动程序void testShell(){ //string str = "cr P1 2 R0 2 R1 4 R2 2 R3 3"; fstream file; string str; string temp; queue<string> strqueue; showMenu(); while (1){ //test.lxsh cout << "shell>>"; cin >> str; //帮助 if (str == "help" || str == "--help" || str == "-help"||str=="man"){ showMenu(); continue; } else if (str == "init"){ init(); } else if (str == "to"){ timeOut(); continue; } else if (str == "show ar"){ //if (running_process == NO_PROCESS_IS_RUNNING){ // LOG("LOG: @testshell,no process is running,create some processes first"); // showMenu(); // continue; //} //else showAllResource(); } else if (str == "show ap"){ showAllProcess(); } else if (str == "top"){ while (1){ timeOut(); cout << endl; showAllResource(); showAllProcess(); Sleep(2000); //system("cls"); } } else{ file.open(str+".txt"); if (!file.is_open()){ LOG("LOG: @testShell,undefined command!!1!"); continue; } else{ while (!file.eof()){ getline(file, str); //cout << str << endl; //字符串解析 if (str.size() != 0){ int i = 0; int j = 0; str += ' '; while (str.find(" ", i) != string::npos){ j = str.find(" ", i); temp = str.substr(i, j - i); strqueue.push(temp); i = j + 1; } } if (strqueue.front() == "cr"){ strqueue.pop(); string name = strqueue.front(); strqueue.pop(); int prio = atoi(strqueue.front().c_str()); strqueue.pop(); //cout << name << " " << prio << endl; map<r_ty, need *> res; //int i = 0; while (!strqueue.empty()){ need *ne = new need; ne->type = getTypeByStr(strqueue.front()); strqueue.pop(); //cout << i << endl; ne->num = atoi(strqueue.front().c_str()); strqueue.pop(); //cout << i++; res[ne->type] = ne; } create(getPCBbyId(0), prio, res, name); } } } } }}void showAllResource(){ cout << "ALL RESOURCES--------------------------------------------------------------------------------"<<endl; for (map<r_ty, RCB*>::iterator it = storage.begin(); it != storage.end(); it++){ cout << getResourceTypeName(it->first) << "|"; for (vector<resource>::iterator res = it->second->res.begin(); res != it->second->res.end(); res++){ cout << " "<< res->r_id << "(" << res->r_st << ") |"; } cout << endl; } cout << "---------------------------------------------------------------------------------------------" << endl;}void showAllProcess(){ cout << "ALL PROCESSES-----------------------------" <<endl; cout << "PID " << "PNAME " << "PRIORITY " <<" queue_now "<< "STATUS|" << endl; for (map<int, PCB*>::iterator it = process_pool.begin(); it != process_pool.end(); it++){ cout << " " << it->second->process_id << " " << it->second->name << " " << it->second->priority << " "<<it->second->queue_now << " " << it->second->p_status <<" |"<< endl; } cout << "-----------------------------------------" << endl;}
main.cpp(shell)
//bug、优化、待完成部分//√+进程调度低优先级进程存在别饿死情况// 可采用多级反馈队列调度算法// 1为每个队列增加时间片属性,优先级越低时间片越长// 2时间片内未运行完成则进入低优先级,queue_now减1.(从2开始递减)// 3使用queue_now标识进程所在队列,所以除初始值外,其他时刻它与priority不一定相同// 4最低优先级不再降低,按照时间片轮转调度//+timeOut 有bug//√+日志文件加上函数位置//√+资源请求数大于系统资源数时崩溃//+test shell//+从文件输入脚本//+日志文件输出问题//同时有两个进程状态为running//从未出阻塞队列#include "data.h"using namespace std;int main(int argc, char **argv){ //加载资源 defineResource(); //创建init,默认init位于资源池的开始,即map<0,init> //init(); testShell(); system("pause"); return 0;}
test.txt
cr Pro1 2 R0 1 R1 2 R2 1 R3 1cr Pro2 0 R0 2 R1 2 R2 2 R3 2cr Pro3 1 R0 1 R1 1 R2 1 R3 1cr Pro4 2 R0 1 R1 1 R2 1 R3 2cr Pro5 1 R0 1 R1 1 R2 2 R3 3
阅读全文
0 0
- 【操作系统】用c++实现简单的进程调度程序
- 操作系统用C语言模拟进程基于优先级的调度程序
- 【操作系统】进程调度实现
- 进程调度---c模拟程序实现
- 操作系统进程调度简单模拟
- 操作系统进程调度模拟程序
- 浅谈操作系统是如何工作的及简单的进程调度的linux实现
- 操作系统用C语言模拟基于时间片进程调度程序
- 操作系统的进程调度算法
- 操作系统的进程调度算法
- 操作系统实验(1)-- 进程调度的设计与实现
- (操作系统)进程调度的设计与实现
- 用C语言实现对N个进程的简单时间片轮转法Round Robin的调度模拟
- 操作系统FCFS,SJF进程调度(C++)
- 操作系统-------进程调度算法(C++实现)
- 操作系统进程调度算法(Java 实现)
- 用C++模拟操作系统进程调度的几种算法
- 操作系统 进程调度 基于时间片轮转(C实现 Visual Stdio 2005)
- 基于Bootstrap的jQuery slider插件的使用bootstrap-slider.js
- 北大OJ 1088
- Docker源码解读:1.flag解读
- Redis+MyBatis自定义注解实现缓存
- Ambari 2.5.0 汉化流程
- 【操作系统】用c++实现简单的进程调度程序
- 2334:Simple prefix compression
- cocos2dx UserDefault存储数据问题
- redis添加访问密码
- 版本管理工具SVN
- 获得表格的行数据
- 如何在 Windows 上安装 Laravel Homestead
- JAVA基础——多线程同步实现(生产者/消费者模型)
- 第6章 电力窃漏电用户自动识别