#include<stdio.h>
#include<stdlib.h>
#define getpch(type) (type*)malloc(sizeof(type))
#define nothing 0
typedef struct pcb{ //自定义结构体:进程管理块pcb
char name[10]; //进程名字
char state; //进程状态
int ntime; //进程需要运行的时间
int rtime; //进程已经运行的时间
struct pcb *link; //进程队列链指针
}PCB;
//初始化就绪队列,进程插入位置的变量,ready首指针,pfend尾指针,p临时变量,stop阻塞队列首指针,stopend阻塞队列尾指针
PCB *ready = nothing, *pfend=nothing,*p=nothing,*stop = nothing,*stopend=nothing;
//使用户仅能输入整数
int geti()
{
char ch;
int i=0;
fflush(stdin); //清除输入缓存 ,防止干扰后续的输入操作
ch=getchar();
while(ch == '\n'){
//printf("\tf输入不能为空..请重新输入\n");
fflush(stdin);
ch=getchar();
}
while(ch!='\n'){ //检验输入是否为合法字符
if(ch>'9' || ch<'0'){
printf("\t输入有误!!输入只能为正整数,请重新输入…\n");
fflush(stdin);
i=0;
ch=getchar();
}else{
i=i*10+(ch-'0'); //字符转换为数字
ch=getchar();
}
}
return i;
}
//先来先服务插入进程
void fcfs()
{
if(!ready){ //就绪队列为空
ready=p;
pfend=p;
}
else{ //就绪队列非空,插入队尾
p->link=pfend->link;
pfend->link=p;
pfend=p;
}
}
/*建立num个进程控制块函数
已运行时间=0,状态=w
*/
void input()
{
int i,num;
printf("\n请输入进程的个数?");
num=geti();
for(i=0;i<num;i++)
{
printf("\n进程号No.%d:\n",i+1);
p=getpch(PCB); // 创建进程块p
printf("\n输入进程名:");
scanf("%s",p->name); // 初始化进程名字
printf("\n输入进程运行时间:");
p->ntime=geti();
printf("\n");
p->rtime=0;
p->state='w'; // 初始化其状态为就绪状态
p->link=nothing;
fcfs(); //按照先来先服务进入就绪队列
}
}
/*显示当前系统内进程及进程信息*/
void disp(PCB *pr)
{
printf("\nname\t state\t ntime\t rtime\t \n");
printf(" |%s\t",pr->name);
printf(" |%c\t",pr->state);
printf(" |%d\t",pr->ntime);
printf(" |%d\t",pr->rtime);
printf("\n");
}
/*建立进程查看函数*/
void check()
{
PCB *pr;
if(ready !=nothing){
printf("\n****当前正在运行的进程是:%s",ready->name);/*显示当前运行的进程*/
disp(ready);
pr=ready->link;
printf("\n****当前就绪队列状态为:\n");/*显示就绪队列状态*/
while(pr!=nothing)
{
disp(pr);
pr=pr->link;
}
}
printf("\n****当前就阻塞队列的状态为:\n");
pr=stop;
while(pr!=nothing){
disp(pr);
pr=pr->link;
}
}
/*撤销进程,进程运行结束*/
void destroy()
{
printf("\n进程[%s]已完成.\n",ready->name);
p=ready;
ready=ready->link;
free(p);
}
/*建立进程就绪函数(进程运行时间到,置就绪状态)*/
void running()
{
(ready->rtime)++;
check();
if(ready->rtime==ready->ntime){
destroy();
return;
}
}
/*阻塞进程*/
void block()
{
if(!stop){//阻塞队列为空
ready->state='b';
//补全代码
}
else{//阻塞队列不为空
ready->state='b';
/补全代码
}
stopend->link=nothing;
}
/*阻塞进程唤醒*/
void wake()
{
if(stop==nothing){
printf("\n阻塞队列为空,请进行其他操作");
return;
}
else{
if(ready!=nothing){//就绪队列不为空
}
else{//就绪队列为空
//待补全
}
//待补全
}
}
int main()
{
char ch;
input();
while(ready!=nothing || stop!=nothing) //系统中存在进程
{
if(ready!=nothing){
printf("\nThe execute name:%s\n",ready->name);
ready->state='R';
//check();
running();
//check();
}
else{
check();
}
printf("\n按i键添加新进程…s键阻塞进程…w键唤醒进程\n按其他任意键继续运行…\n");
fflush(stdin);
ch=getchar();
if(ch=='i' || ch=='I')
input();
if(ch=='s' || ch=='S')
block();
if(ch=='w' || ch=='W')
wake();
}
printf("\n\n进程已经完成\n");
getchar();
return 0;
}
能否补全一下阻塞和唤醒代码
- 写回答
- 好问题 0 提建议
- 追加酬金
- 关注问题
- 邀请回答
-
6条回答 默认 最新
关注 引自免费微信小程序:皆我百晓生
在给定的代码中,你需要实现阻塞和唤醒功能。首先,我们来看如何修改
block()
函数以将进程加入阻塞队列。在
block()
函数中,你需要检查阻塞队列是否为空。若为空,则将当前进程添加到阻塞队列的头部。若不为空,将当前进程添加到阻塞队列的尾部。下面是修改后的block()
函数:void block() { if (!stop) // 阻塞队列为空 { ready->state = 'b'; stop = ready; stopend = ready; } else // 阻塞队列不为空 { ready->state = 'b'; stopend->link = ready; stopend = ready; } }
接下来,我们需要修改
wake()
函数以从阻塞队列中唤醒一个进程并将其放入就绪队列。当就绪队列为空时,我们将阻塞队列的第一个进程移动到就绪队列的头部。以下是修改后的wake()
函数:void wake() { if (stop == nothing) { printf("\n阻塞队列为空,请进行其他操作"); return; } else { if (ready != nothing) // 就绪队列不为空 { // 暂时保存就绪队列中的第一个进程,用于恢复原样 PCB *temp = ready; running(); // 运行就绪队列中的下一个进程 ready = temp; } else // 就绪队列为空 { ready = stop; // 阻塞队列的第一个进程变成就绪队列的第一个进程 if (ready->link) // 如果阻塞队列还有其他进程 stop = ready->link; else stop = nothing; // 否则阻塞队列也变为为空 stopend = nothing; } // 更新阻塞队列的尾部指针 if (stop != nothing) stopend = stop; } }
现在,代码应该可以正确地处理阻塞和唤醒操作了。请注意,这个实现没有考虑到多进程并发的情况,实际应用中可能需要添加互斥锁等同步机制来保证线程安全。另外,为了简化代码,这里没有处理异常情况,例如尝试唤醒一个已经不存在的阻塞进程。在实际项目中,你应该增加适当的错误检查和处理。
解决 无用评论 打赏 举报 编辑记录
悬赏问题
- ¥15 CCF-CSP 2023 第三题 解压缩(50%)
- ¥30 comfyui openpose报错
- ¥20 Wpf Datarid单元格闪烁效果的实现
- ¥15 图像分割、图像边缘提取
- ¥15 sqlserver执行存储过程报错
- ¥100 nuxt、uniapp、ruoyi-vue 相关发布问题
- ¥15 浮窗和全屏应用同时存在,全屏应用输入法无法弹出
- ¥100 matlab2009 32位一直初始化
- ¥15 Expected type 'str | PathLike[str]…… bytes' instead
- ¥15 三极管电路求解,已知电阻电压和三级关放大倍数