20211325 2023-2024-1 《信息安全系统设计与实现(上)》第六周学习笔记

发布时间 2023-10-21 16:11:07作者: STERNSTUN

20211325 2023-2024-1 《信息安全系统设计与实现(上)》第六周学习笔记

一、任务要求

1.自学教材第3章,提交学习笔记(10分),评分标准如下 1. 知识点归纳以及自己最有收获的内容,选择至少2个知识点利用chatgpt等工具进行苏格拉底挑战,并提交过程截图,提示过程参考下面内容 (4分) “我在学***X知识点,请你以苏格拉底的方式对我进行提问,一次一个问题” 核心是要求GPT:“请你以苏格拉底的方式对我进行提问” 然后GPT就会给你提问,如果不知道问题的答案,可以反问AI:“你的理解(回答)是什么?” 如果你觉得差不多了,可以先问问GPT:“针对我XXX知识点,我理解了吗?” GPT会给出它的判断,如果你也觉得自己想清楚了,可以最后问GPT:“我的回答结束了,请对我的回答进行评价总结”,让它帮你总结一下。

2. 问题与解决思路,遇到问题最先使用chatgpt等AI工具解决,并提供过程截图(3分)

3. 实践过程截图,代码链接(2分)

4. 其他(知识的结构化,知识的完整性等,提交markdown文档,使用openeuler系统等)(1分)

二、知识点归纳总结

1、知识点归纳

第3章 Unix/Linux进程管理

1、进程——是对映像的执行
  • 如何产生进程:执行一个程序或指令

程序放在实体磁盘当中,然后透过使用者的执行来触发,触发后会加载到内存中成为一个个体,那就是进程,为了操作系统可管理这个进程,因此进程有给予执行者的权限、属性参数,并包括程序所需要的脚本与数据或文件数据等,最后在给予一个PID

  • 关于子进程与父进程
    在bash中再调用bash
注意:当父进程存在消灭子进程,父进程会主动再生成一支,要找出父进程并消灭
  • fork and exec进程呼叫流程
    进程会有父进程以复制的方式产生一个一模一样的子进程,然后被复制出来的子进程再以exec的方式来执行实际要进行的程序,最终成为了一个子进程的存在

常驻在内存中的进程通常是负责一些系统所提供的功能以服务用户各项工作,这些常驻程序被称为:服务(daemon)

一般daemon类型的程序都会加上d在文件名后头
在单一bash接口下进行多个工作:
命令后加& 表示将命令放置于背景中执行
  • 进程同步
    进程同步是指控制和协调进程交互以确保其正确执行所需的各项规则和机制。
    最简单的进程同步工具是休眠和唤醒操作。
为实现休眠操作,我们可以在 PROC结构体中添加一个event字段,并实现ksleep(int event)函数,使进程进入休眠状态。
当某个等待时间发生时,另一个执行实体(可能是某个进程或中断处理程序)将会调用 kwakeup(event)。
唤醒正处于休眠状态等待该事件值的所有程序。
如果没有任何程序休眠等待该程序,kwakeup()就不工作,即不执行任何操作。

进程睡眠状态有两种:

可中断的睡眠状态,其状态标志位TASK_INTERRUPTIBLE
不可中断的睡眠状态,其状态标志位为TASK_UNINTERRUPTIBLE
  • 进程终止
正常终止:进程调用exit(value),发出_exit(value)系统调用来执行在操作系统内核中的kexit(value)。
异常终止:进程因某个信号而异常终止。
2、多任务处理

(1)多任务处理系统

  • type.h文件
type.h文件定义了系统常数和表示进程的简单PROC结构体。
  • ts.s文件
ts.s在32位GCC汇编代码中可实现进程上下文切换。
  • queue.c文件
queue.c文件可实现队列和链表操作函数。
enqueue()函数按优先级将PROC输入队列。在优先级队列中,具有相同优先级的进程按先进先出(FIFO).
dequeue()函数可返回从队列或链表中的第一个元素。printlist()函数可打印链表元素。
  • t.c文件
t.c文件定义MT系统数据结构、系统初始化代码和进程管理函数。
3、进程管理的系统调用

(1)fork()

int pid = fork()
fork()创建子进程并返回子进程的pid。
在fork函数执行完毕后,如果创建新进程成功,则出现两个进程,一个是子进程,一个是父进程。

 

(2)wait()

int wait(int *status)
父进程一旦调用了wait就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出,如果让它找到了这样一个已经变成僵尸的子进程,wait就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait就会一直阻塞在这里,直到有一个出现为止。

 

(3)exec()
用fork函数创建子进程后,子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程执行的程序完全替换为新程序,而新程序则从其main函数开始执行。

函数原型
*#include <unistd.h>*
*int execl( const char *pathname, const char *arg0, ... /* (char *)0 */ );*
*int execv( const char *pathname, char *const argv[] );*
*int execle( const char *pathname, const char *arg0, ... /* (char *)0, char *const envp[] */ );*
*int execve( const char *pathname, char *const argv[], char *const envp[] );*
*int execlp( const char *filename, const char *arg0, ... /* (char *)0 */ );*
*int execvp( const char *filename, char *const argv[] );*
返回值:六个函数的返回值,若出错则返回-1,若成功则不返回值

  

(4)exit()

int atexit(void (*func)(void));

 

4、进程的执行模式
  • 中断:中断是外部设备发送给 CPU的信号,请求CPU服务。

  • 陷阱:陷阱是错误条件,例如无效地址、非法指令、除以0等、这些错误条件被CPU识别为异常,使得CPU进入 Kmode 来处理错误。

  • 系统调用:系统调用(简称syscall)是一种允许Umode 进程进入Kmode 以执行内核函数的机制。如果发生错误,外部全局变量 errno(在errno. h中)会包含一个ERROR代码,用于标识错误。用户可使用库函数
    perror( "error message");

5、I/O重定向
  • 文件流和文件描述符
    每个文件流都是指向执行映像堆区中FILE结构体的一个指针。每个文件流对应Linux内核中的一个打开文件。每个打开文件都用一个文件描述符(数字)表示。
  • 文件流I/O和系统调用
当进程执行库函数
scanf("%s",&item);
它会试图从stdin文件输入一个(字符串)项,指向FILE结构体。
6、管道
  • 管道命令处理
在Unix/Linux中,命令行cmd1 | cmd2
sh将通过一个进程运行cmd1,并通过另一个进程运行cmd2,他们通过一个管道连接在一起,因此cmd1的输出变为cmd2的输入
  • 命令管道
    命名管道又叫做FIFO。它们有“名称”,并在文件系统中以特殊文件的形式存在。

三、课本实践内容与截图

实践1:env

实践2:ulimit -a

实践3:fork()函数

#include <unistd.h>
#include <stdio.h>
int main ()
{
pid_t fpid; //fpid表示fork函数返回的值
int count=0;
fpid=fork();
if (fpid < 0)
printf("error in fork!");
else if (fpid == 0)
{
printf("i am the child process, my process id is %d/n",getpid());
printf("我是爹的儿子/n");
count++;
}
else
{
printf("i am the parent process, my process id is %d/n",getpid());
printf("我是孩子他爹/n");
count++;
}
printf("统计结果是: %d/n",count);
return 0;
}

 四、课堂代码实现

五、苏格拉底挑战

(1)多任务处理系统

(2)管道