
四、实验思路和设计
1、进程管理
(1)程序流程图
由学生自行完成。
(2)主要程序代码
//PCB结构体
struct pcb{
int id; //进程序号
int ra; //所需资源A的数量
int rb; //所需资源B的数量
int rc; //所需资源C的数量
int ntime; //所需的时间片个数
int rtime; //已经运行的时间片个数
char state; //进程状态
struct pcb next;
} hready=NULL,hblock=NULL,p; //hready,hblock分别为指向就绪和阻塞队列
typedef struct pcb PCB;
int m,n,r,a,b,c,h=0,i=1,time1Inteval; //m为要模拟的进程个数,n为初始化进程个数
//r为可随机产生的进程数(r=m-n)
//a,b,c分别为A,B,C三类资源的总量
//i为进城计数,i=1…n
//h为运行的时间片次数,time1Inteval为时间片大小(毫秒)
//建立一个PCB结构体型的空链表
PCB increat(void)
{ PCB head;
head=NULL;
return(head);
}
//从链表起始地址开始输出该链表的内容
void disp(PCB head)
{PCB p1;
p1=head;
AnsiString str2;
if(head!=NULL) //链表非空
{
do
{
str2+=" ";
str2+=IntToStr(p1->id);str2+=" ";
str2+=(p1->state);str2+=" ";
str2+=IntToStr(p1->ra);str2+=" ";
str2+=IntToStr(p1->rb);str2+=" ";
str2+=IntToStr(p1->rc);str2+=" ";
str2+=IntToStr(p1->ntime);str2+=" ";
str2+=IntToStr(p1->rtime);str2+="\r\n";
p1=p1->next;
}while(p1!=NULL); //不断输出进程的信息,直到链尾!
} //if
else
{ str2+="\t\t该 队 列 中 没 有 进 程!\r\n" ;}
Form1->Memo1->Lines->Add(str2);
}
//将进程插入到链尾(包括就绪队列和阻塞队列)
PCB insert(PCB head,PCBpcb) //带两个指针形参:队列指针和当前进程PCB
{
PCB pi,p1;
p1=head;
pi=pcb;
if (head==NULL)
{
head=pi;
pi->next=NULL;
}
else
{
while(p1->next!=NULL)
{p1=p1->next;}
p1->next=pi;
pi->next=NULL;
}
return(head);
}
//对进程进行初始化,建立就绪队阻塞队列。
void input()
{
AnsiString str1;
m=StrToInt (Form1->Edit1->Text); //读取要模拟的进程总数给m
n=StrToInt (Form1->Edit2->Text); //读取需初始化进程数给n
a=StrToInt (Form1->Edit3->Text); //读取A类资源的总数给a
b=StrToInt (Form1->Edit4->Text); //读取B类资源的总数给b
c=StrToInt (Form1->Edit5->Text); //读取C类资源的总数给c
time1Inteval=StrToInt(Form1->Edit6->Text); //读取时间片长度给time1Inteval
Form1->Timer1->Interval=time1Inteval;
r=m-n; //计算可随机产生的进程数为r
for(i=1;i<=n;i++) //初始化n个进程信息
{
p=getpcb(PCB); // #define getpcb(type) (type)malloc(sizeof(type))
p->id=i;
str1+=" 产生进程ID:";str1+=IntToStr(p->id);str1+="\r\n";
p->ra=(random(a-3)+3);
str1+=" 所需A类资源数:";str1+=IntToStr(p->ra);str1+="\r\n";
p->rb=(random(b));
str1+=" 所需B类资源数:";str1+=IntToStr(p->ra);str1+="\r\n";
p->rc=(random(c-2)+2);
str1+=" 所需C类资源数:";str1+=IntToStr(p->ra);str1+="\r\n";
p->ntime=(random(5)+1);
str1+=" 所需时间片个数:";str1+=IntToStr(p->ntime);str1+="\r\n";
p->rtime=0;
p->next=NULL;
if (((a-(p->ra))>=0)&&((b-(p->rb))>=0)&&((c-(p->rc))>=0)) //如果资源符合所需要求
{ //则写入就绪队列队尾
a=a-(p->ra); //当前所剩A类资源数目
b=b-(p->rb); //当前所剩B类资源数目
c=c-(p->rc); //当前所剩C类资源数目
p->state='W';
hready=insert(hready,p); //将进程插入就绪队列
}//if
else //如果资源不符合所需要求,则写入阻塞队列队尾
{
p->state='B';
hblock=insert(hblock,p);
} //if
str1+=" 当前进程状态:";
str1+=(p->state);
str1+="\r\n";
str1+="\r\n";
}//for
Form1->Memo1->Lines->Add(str1);
}
//输出就绪队列和阻塞队列的信息
void outputall()
{
AnsiString str1,str2,str3;
str3+="\r\n" ;
str3+="= = = = = = = = = = = = = = = CPU时间片运行了: " ;
str3+=IntToStr(h);
str3+=" 次= = = = = = = = = = = = = = =\r\n";
Form1->Memo1->Lines->Add(str3);
str1+="当 前 就 绪 队 列 的 信 息" ;
str1+="\r\n" ;
str1+="进程ID 进程状态 A资源数 B资源数 C资源数 需要时间片 已运行时间片";
Form1->Memo1->Lines->Add(str1);
disp(hready);
str2+="当 前 阻 塞 队 列 的 信 息";
str2+="\r\n" ;
str2+="\r\n";
str2+="进程ID 进程状态 A资源数 B资源数 C资源数 需要时间片 已运行时间片";
Form1->Memo1->Lines->Add(str2);
disp(hblock);
}
//运行就绪队列的头进程,运行一个时间片(FCFS),轮转一个时间片
PCB running(PCB head)
{
PCB p1;
p1=head;
AnsiString str4;
If (p1->next==NULL) head=increat();
else {head=p1->next; }
p1->state='R'; //进程状态由就绪转向运行
(p1->rtime)++; //已运行时间片数增加1
h++;
str4+="~~~~~~~~~~~~~~~~ 当前正在运行的进程ID是: ";
str4+=IntToStr(p1->id);
str4+=" ~~~~~~~~~~~~~~~~~~\r\n";
str4+="进程ID 进程状态 A资源数 B资源数 C资源数 需要时间片 已运行时间片\r\n";
str4+=" ";
str4+=IntToStr(p1->id);str4+=" ";
str4+=(p1->state);str4+=" ";
str4+=IntToStr(p1->ra);str4+=" ";
str4+=IntToStr(p1->rb);str4+=" ";
str4+=IntToStr(p1->rc);str4+=" ";
str4+=IntToStr(p1->ntime);str4+=" ";
str4+=IntToStr(p1->rtime);str4+=" ";
Form1->Memo1->Lines->Add(str4);
if(p1->ntime==p1->rtime) //如果已经运行的时间片到达所需次数,该进程结束
{
str4+="\r\n\r\n\t\tID号为:";
str4+=IntToStr(p1->id);
str4+=" 的进程已经完成!!!";
Form1->Memo1->Lines->Add(str4);
a=a+(p1->ra);
b=b+(p1->rb);
c=c+(p1->rc);
free(p1); //释放当前指针
}
else //如果已经运行的时间片未到达所需次数,该进程运行一个时间片后进入就绪队列尾
{
p1->state='W';
head=insert(head,p1);
}
return(head);
}
//检测当前资源数目是否满足阻塞队列里进程的需求
void testblock()
{
PCB p1,p2;
p1=hblock;
p2=hblock;
AnsiString str5;
while((hblock!=NULL)&&(p1!=NULL))
{
if((a-(p1->ra)>=0)&&(b-(p1->rb)>=0)&& (c-(p1->rc)>=0)) //如果满足
{if(p1==hblock)
{
hblock=p1->next;
p1->state='W';
hready=insert(hready,p1); //将阻塞的进程插入就绪队列
a=a-(p->ra);
b=b-(p->rb);
c=c-(p->rc);
str5="\tID号为: " ;
str5+=IntToStr(p1->id);
str5+=" 的进程由阻塞队列转入就绪队列!\r\n";
p1=hblock;
} //if(p1==hblock)
else
{p2->next=p1->next;
p1->state='W';
hready=insert(hready,p1);
str5="\tID号为: " ;
str5+=IntToStr(p1->id);
str5+=" 的进程由阻塞队列转入就绪队列!\r\n";
p1=p2->next;
}//else
} //大if
else
{p2=p1;
p1=p1->next;
} //else
Form1->Memo1->Lines->Add(str5);
} //whlie
}
//检测是否有新的进程产生,随机产生新进程
void testnew()
{
int t;
AnsiString str6;
if(r>0) //r=m-n为可随机产生的进程数目
{
t=random(9); //生成随机数
if(t<=7) //如果随机数小于等于7,则产生新进程,否则不产生
{
p=getpcb(PCB);
str6+="有新的进程申请加入:\r\n" ;
p->id=i++; //i为全程变量,表示进程号?
str6+="进程ID:";
str6+=IntToStr(p->id);
str6+="\r\n";
p->ra=(random(a-3)); //随机分配资源
str6+="所需A类资源数:";
str6+=IntToStr(p->ra);
str6+="\r\n";
p->rb=(random(b-3));
str6+="所需B类资源数:";
str6+=IntToStr(p->rb);
str6+="\r\n";
p->rc=(random(c-3));
str6+="所需C类资源数:";
str6+=IntToStr(p->rc);
str6+="\r\n";
p->ntime=(random(5)+1); //随机分配时间片总数
str6+="所需时间片个数:";
str6+=IntToStr(p->ntime);
str6+="\r\n";
p->rtime=0; //已运行时间片数初始为0
p->next=NULL;
if (((a-(p->ra))>=0)&&((b-(p->rb))>=0)&&((c-(p->rc))>=0))
{ //进程满足要求,进入就绪队列
a=a-(p->ra); //分配资源给该进程,总资源数减少
b=b-(p->rb);
c=c-(p->rc);
p->state='w';
str6+="当前进程状态:";
str6+=(p->state);
str6+="\r\n";
hready=insert(hready,p);
str6+="资源满足新进程需求,该进程进入就绪队列!";
}//if
else //进程不满足要求,进入阻塞队列
{
p->state='B';
hblock=insert(hblock,p);
str6+="当前进程状态:";
str6+=(p->state);
str6+="\r\n";
str6+="资源不能满足新进程需求,该进程进入阻塞队列!" ;
}//else
}//if (t<=7)
Form1->Memo1->Lines->Add(str6);
}//if(r>0)
r--;
}
//系统三类资源变化情况的显示
void rescore()
{
if(a>a1) {Form1->Edit7->Text=IntToStr(a1);}
if(a<0) {Form1->Edit7->Text=0;}
if(a>=0&&a<a1) {Form1->Edit7->Text=IntToStr(a);}
if(b>b1) {Form1->Edit8->Text=IntToStr(b1);}
if(b<0) {Form1->Edit8->Text=0;}
if(b>=0&&b<=b1) {Form1->Edit8->Text=IntToStr(b); }
if(c>c1) {Form1->Edit9->Text=IntToStr(c1);}
if(c<0) {Form1->Edit9->Text=0;}
if(c>=0&&c<=c1) {Form1->Edit9->Text=IntToStr(c); }
}
void __fastcall TForm1::Timer1Timer(TObject Sender)
{
runFcfs(); //先来先服务(FCFS)调度算法
}
//先来先服务(FCFS)调度算法
void runFcfs()
{
AnsiString str;
if(form1_hready!=NULL) //如果就绪队列为非空,则不断运行,直到就绪队列为空为止
{
outputall(); //输出就绪队列和阻塞队列的信息
form1_hready=running(form1_hready); //将就绪队列的第一个进程运行一个时间片
testblock(); //检查阻塞队列是否有进程可以进入就绪队列
testnew(); //检查是否有新进程产生
rescore() ; //系统三类资源变化情况的显示
}
else
{
Form1->Timer1->Enabled=false;
Form1->Edit7->Text=IntToStr(a1);
Form1->Edit8->Text=IntToStr(b1);
Form1->Edit9->Text=IntToStr(c1);
str+="\r\n\r\n<<<<<<<<<<<<<<<所 有 的 进 程 都 已 经 成 功 运 行 结 束 !>>>>>>>>>>>>>>";
Form1->Memo1->Lines->Add(str);
}
}
//将结果保存成txt文件
void __fastcall TForm1::N8Click(TObject Sender)
{
if(Form1->SaveDialog1->Execute())
{
FILE fp=fopen(Form1->SaveDialog1->FileNamec_str(),"w");
if(fp==NULL)
{
MessageBox(NULL,"打开文件出错","信息",MB_OK);
return;
}
for(int i=0;i<Form1->Memo1->Lines->Count;i++)
{ fputs(Form1->Memo1->Lines->Strings[i]c_str(),fp);
fputc('\n',fp);
}
fclose(fp);
}
}
//开始模拟按钮单击执行函数
void __fastcall TForm1::Button1Click(TObject Sender)
{
runmain();
Form1->Button1->Enabled=false;
Form1->Edit1->Enabled=false;
Form1->Edit2->Enabled=false;
Form1->Edit3->Enabled=false;
Form1->Edit4->Enabled=false;
Form1->Edit5->Enabled=false;
Form1->Edit6->Enabled=false;
}
//清除屏幕按钮单击执行函数
void __fastcall TForm1::Button2Click(TObject Sender)
{
Form1->Memo1->Clear();
Button1->Enabled=true;
h=0;
Form1->Edit1->Enabled=true;
Form1->Edit2->Enabled=true;
Form1->Edit3->Enabled=true;
Form1->Edit4->Enabled=true;
Form1->Edit5->Enabled=true;
Form1->Edit6->Enabled=true;
}
//运行的主函数
void runmain()
{
AnsiString str,str1;
input();
Form1->Timer1->Enabled=true; //触发时钟,调用runFCFS。
str+="\r\n";
}
似乎LD_PRELOAD是个好办法唉~ 但是感觉这种设置env的办法杀伤性太广等等看其他方法 OJ也面临这样的问题 但是那个可以从源代码就可以掌控LZ的情况是可以从源代码编译B呢还是你只能得到一个执行文件
目录
众所周知,CPU是计算机的核心,它承担了所有的计算任务。而 *** 作系统是计算机的管理者,是一个大管家,它负责任务的调度,资源的分配和管理,统领整个计算机硬件。应用程序是具有某种功能的程序,程序运行与 *** 作系统之上
在很早的时候计算机并没有线程这个概念,但是随着时代的发展,只用进程来处理程序出现很多的不足。如当一个进程堵塞时,整个程序会停止在堵塞处,并且如果频繁的切换进程,会浪费系统资源。所以线程出现了
线程是能拥有资源和独立运行的最小单位,也是程序执行的最小单位。一个进程可以拥有多个线程,而且属于同一个进程的多个线程间会共享该进行的资源
① 200 多本 Python 电子书(和经典的书籍)应该有
② Python标准库资料(最全中文版)
③ 项目源码(四五十个有趣且可靠的练手项目及源码)
④ Python基础入门、爬虫、网络开发、大数据分析方面的视频(适合小白学习)
⑤ Python学习路线图(告别不入流的学习)
私信我01即可获取大量Python学习资源
进程时一个具有一定功能的程序在一个数据集上的一次动态执行过程。进程由程序,数据集合和进程控制块三部分组成。程序用于描述进程要完成的功能,是控制进程执行的指令集;数据集合是程序在执行时需要的数据和工作区;程序控制块(PCB)包含程序的描述信息和控制信息,是进程存在的唯一标志
在Python中,通过两个标准库 thread 和 Threading 提供对线程的支持, threading 对 thread 进行了封装。 threading 模块中提供了 Thread , Lock , RLOCK , Condition 等组件
在Python中线程和进程的使用就是通过 Thread 这个类。这个类在我们的 thread 和 threading 模块中。我们一般通过 threading 导入
默认情况下,只要在解释器中,如果没有报错,则说明线程可用
守护模式:
现在我们程序代码中,有多个线程, 并且在这个几个线程中都会去 *** 作同一部分内容,那么如何实现这些数据的共享呢?
这时,可以使用 threading库里面的锁对象 Lock 去保护
Lock 对象的acquire方法 是申请锁
每个线程在 *** 作共享数据对象之前,都应该申请获取 *** 作权,也就是调用该共享数据对象对应的锁对象的acquire方法,如果线程A 执行了 acquire() 方法,别的线程B 已经申请到了这个锁, 并且还没有释放,那么 线程A的代码就在此处 等待 线程B 释放锁,不去执行后面的代码。
直到线程B 执行了锁的 release 方法释放了这个锁, 线程A 才可以获取这个锁,就可以执行下面的代码了
如:
到在使用多线程时,如果数据出现和自己预期不符的问题,就可以考虑是否是共享的数据被调用覆盖的问题
使用 threading 库里面的锁对象 Lock 去保护
Python中的多进程是通过multiprocessing包来实现的,和多线程的threadingThread差不多,它可以利用multiprocessingProcess对象来创建一个进程对象。这个进程对象的方法和线程对象的方法差不多也有start(), run(), join()等方法,其中有一个方法不同Thread线程对象中的守护线程方法是setDeamon,而Process进程对象的守护进程是通过设置daemon属性来完成的
守护模式:
其使用方法和线程的那个 Lock 使用方法类似
Manager的作用是提供多进程共享的全局变量,Manager()方法会返回一个对象,该对象控制着一个服务进程,该进程中保存的对象运行其他进程使用代理进行 *** 作
语法:
线程池的基类是 concurrentfutures 模块中的 Executor , Executor 提供了两个子类,即 ThreadPoolExecutor 和 ProcessPoolExecutor ,其中 ThreadPoolExecutor 用于创建线程池,而 ProcessPoolExecutor 用于创建进程池
如果使用线程池/进程池来管理并发编程,那么只要将相应的 task 函数提交给线程池/进程池,剩下的事情就由线程池/进程池来搞定
Exectuor 提供了如下常用方法:
程序将 task 函数提交(submit)给线程池后,submit 方法会返回一个 Future 对象,Future 类主要用于获取线程任务函数的返回值。由于线程任务会在新线程中以异步方式执行,因此,线程执行的函数相当于一个“将来完成”的任务,所以 Python 使用 Future 来代表
Future 提供了如下方法:
使用线程池来执行线程任务的步骤如下:
最佳线程数目 = ((线程等待时间+线程CPU时间)/线程CPU时间 ) CPU数目
也可以低于 CPU 核心数
使用线程池来执行线程任务的步骤如下:
关于进程的开启代码一定要放在 if __name__ == '__main__': 代码之下,不能放到函数中或其他地方
开启进程的技巧
开启进程的数量最好低于最大 CPU 核心数
以上就是关于求代码~ *** 作系统 进程管理实验 语言C++ 要求如下:全部的内容,包括:求代码~ *** 作系统 进程管理实验 语言C++ 要求如下:、python进程池里的进程是怎么执行的、小白都看懂了,Python 中的线程和进程精讲,建议收藏等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)