学习笔记六
一. 作业要求
自学教材第3章,提交学习笔记(10分),评分标准如下
-
知识点归纳以及自己最有收获的内容,选择至少2个知识点利用chatgpt等工具进行苏格拉底挑战,并提交过程截图,提示过程参考下面内容 (4分)
“我在学***X知识点,请你以苏格拉底的方式对我进行提问,一次一个问题”
核心是要求GPT:“请你以苏格拉底的方式对我进行提问”
然后GPT就会给你提问,如果不知道问题的答案,可以反问AI:“你的理解(回答)是什么?”
如果你觉得差不多了,可以先问问GPT:“针对我XXX知识点,我理解了吗?”
GPT会给出它的判断,如果你也觉得自己想清楚了,可以最后问GPT:“我的回答结束了,请对我的回答进行评价总结”,让它帮你总结一下。
-
问题与解决思路,遇到问题最先使用chatgpt等AI工具解决,并提供过程截图(3分)
-
实践过程截图,代码链接(2分)
-
其他(知识的结构化,知识的完整性等,提交markdown文档,使用openeuler系统等)(1分)
二. 知识点总结
1. 多任务处理系统
(1)type.h文件
type.h文件定义了系统常数和表示进程的简单PROC结构体
/*********** type.h file ************/
#define NPROC 9
#define SSIZE 1024
// PROC status
#define FREE 0
#define READY 1
#define SLEEP 2
#define ZOMBIE 3
typedef struct proc{
struct proc *next;
int *ksp;
int pid;
int status;
int priority;
int kstack [SSIZE];
}PROC;
后面,我们在扩展 MT系统时,应向PROC结构体中添加更多的字段。
(2)ts.s文件
ts.s在32位GCC汇编代码中可实现进程上下文切换。
#------------- ts,s file file-------
.globl running,scheduler, tswitch
tSwitch:
SAVE:pushl %eax :
pushl %ebx
pushl %ecx
pushl %edx
pushl %ebp
pushl %esi
pushl %edi
pushf1
movl running, Sebx
mov1 # esp,4(%ebx)
FIND: call scheduler
RESUME: movl running,8ebx
Movl 4(%ebx),%esp
popf1
popl %edi
popl %esi
popl %ebp
popl %edx
popl %ecx
popl %ebx
popl %eax
ret
# stack contents=|retPC|eax|ebx|ecx|edx|ebp|esi|edi|eflag|
# -2 -3 -4 -5 -6 -7 -8 -9 -1
(3)queue.c文件
queue.c文件可实现队列和链表操作函数。
/***************** queue.C file*****************/
int enqueue(PROC **queue,PROC *p)
{
PROC *q = *queue;
if(q == 0 || p->priority> q->priority){
*queue = p;
p->next = q;
}
else{
while(g->next && p->priority <= q->next->priority)
q = q->next;
p->next = q->next;
q->next = p;
}
}
PROC *dequeue (PROC **queue)
{
PROC *p = *queue;
if (p)
*queue =(*queue)->next;
return p;
}
int printList(char *name,PROC *p)
{
printf("%s = ",name);
while(p){
printf("[8d %d]->",p->pid,p->priority);
p = p->next;
}
printf("NULL\n");
}
(4)t.c文件
t.c文件定义MT系统数据结构、系统初始化代码和进程管理函数。
2. 多任务处理系统代码介绍
(1)虚拟CPU:MT系统在Linux下编译链接为
gcc -m32 t.c ts.s
(2)init():当MT系统启动时,main()函数调用init()以初始化系统。
(3)P0调用kfork()来创建优先级为1的子进程P1,并将其输入就绪队列中。
(4)tswitich():tswitch()函数实现进程上下文切换。
(5).1 tswitch()中的SAVE函数:当正在执行的某个任务调用tswitch()时,它会把返回地址保存在堆栈上,并在汇编代码中进入tswitch()。
(6).2 scheduler():在执行了SAVE函数之后,任务调用scheduler()来选择下一个正在运行的任务。
(7).3 tswitch()中的RESUME函数
(8)kfork():kfork()函数创建一个子任务并将其输入readyQueue中。
(9)body():所有创建的任务都执行同一个body()函数。
(10)空闲任务 P0:P0的特殊之处在于它所在任务中具有最低的优先级
(11)运行多任务处理(MT)系统
3. 进程同步
(1)睡眠模式
为实现休眠操作,我们可以在 PROC结构体中添加一个event字段,并实现ksleep(int event)函数,使进程进入休眠状态。接下来,我们将假设对 PROC结构体进行修改以包含加粗显示的添加字段。
typedef struct proc{
struct proc *next;
int*ksp;
int pid;
int ppid;
int status;
int priority;
int event;
int exitCode;
struct proc *child;
struct proc *sibling;
struct proc *parent;
int kstack[1024];
}PROC;
(2)唤醒操作
当某个等待时间发生时,另一个执行实体(可能是某个进程或中断处理程序)将会调用 kwakeup(event)。唤醒正处于休眠状态等待该事件值的所有程序。如果没有任何程序休眠等待该程序,kwakeup()就不工作,即不执行任何操作。Kwakeup()的算法是:
/********** Algorithm of kwakeup(int event)*********/
// Assume SLEEPing proCs are in a global sleepiist
for each PROC *p in sleepList do {
if (p->event == event){
delete D from sleepLiBt;
p->8tatu8 = READY;
enqueue(EreadyQueue,p);
}
}
4. 进程终止
● 正常终止:进程调用exit(value),发出 exit(value)系统调用来执行在操作系统内核
中的 kexit(value),这就是我们本节要讨论的情况。
● 异常终止:进程因某个信号而异常终止。信号和信号处理将在后面第6章讨论。
在这两种情况下,当进程终止时,最终都会在操作系统内核中调用kexit()。
5. MT系统中的进程管理
完善基础MT系统,实现MT系统的进程管理函数:
(1)用二叉树的形式实现进程家族树。
(2)实现 ksleepO()和kwakeup()进程同步函数。
(3)实现kexit()和kwait()进程管理函数。
(4)添加"w"命令来测试和演示等待操作。
6. I/O重定向
重定向标准输出
当进程执行库函数
printf("format=%s\n",items);
它试图将数据写入 stdout 文件FILE 结构体中的 fbuf[],这是缓冲行。如果 fbuf[]有一个完整的行,它会发出一个write系统调用,将数据从 fbuf[]写入文件描述符1,映射到终端屏幕上。要想将标准输出重定向到一个文件,需执行以下操作。
c1ose(1);
open("filename",O_WRONLY|O_CREAT,0644);
更改文件描述符1,指向打开的文件名。然后,stdout 的输出将会转到该文件而不是屏幕。同样,我们也可以将stderr重定向到一个文件。当某进程(在内核中)终止时,它会关闭所有打开的文件。
三. 代码实现
1. sh的实现
2. 通过ps命令得到一个进程列表:
3. 管道:
4. fork()实现:
5. 进程执行顺序演示:
删除第一行注释:
删除第二行注释:
四. 利用chatgpt提问
标签:queue,int,笔记,next,学习,MT,进程,PROC From: https://www.cnblogs.com/llwwjj/p/17775709.html