20211301 郑润芃 学习笔记6
第三章教材知识总结
3.1 多任务处理
-
多任务处理:指同时进行几项独立活动的能力
-
单CPU : 一次只能执行一个任务
-
多任务处理:通过不同任务之间多路复用CPU的执行时间
-
上下文切换:不同人物之间的执行切换机制
-
并发:逻辑并行性
3.2 进程的概念
-
进程:对映像的执行
-
执行映像:包含执行代码、数据和堆栈的存储区
-
PROC 结构体:
名称 | 功能 |
---|---|
next | 在各种动态数据结构中维护PROC结构体 |
ksp | 保护堆栈指针 |
pid | 表示进程ID编号 |
ppid | 父进程id编号 |
status | 进程当前状态 |
kstack | 进程执行的堆栈 |
3.8 进程管理的系统调用
- fork:创建子进程,返回子进程的pid 失败则返回-1
- 左侧显示pi映像,在Umode下发出系统调用pid=fork()
- pi转到Kmode执行内核中响应的kfork()函数
- 创建完子进程后,Pi返回语句
- 子进程Pj运行时,会退出Kmode并返回相同语句
-
进程执行顺序:顺序由优先级决定,可以轮流进行
-
进程终止:有两种方式
- 正常终止:exit()函数执行清理工作,发出_exit(value)系统调用,退出值0表示正常终止。通知父进程。
- 异常终止:遇到非法指令、越权、除零等错误,内核异常处理程序将陷阱错误类型转换为一个信号。
-
等待子进程终止:任何时候都可以使用系统调用等待僵尸子进程
-
subreaper进程:处理孤儿进程
-
exec():更改进程的执行映像
- argv[]布局
- 环境变量:为当前sh定义的变量,由子sh或进程继承
3.9 I/O 重定向
-
文件流:每个文件流对应linux内核中的一个打开文件,每个打开文件都用一个文件描述符表示
-
重定向标准输入:close系统调用会关闭文件描述符0,open打开文件,使用最小的未使用描述符数值作为文件描述符
3.10 管道
-
管道:用于进程交换数据的单向进程间通信通道,有一个读取端和写入端
-
双向管道:可以双向传输
-
命名管道:不相关进程之间的FIFO通信通道
-
管道编程:内核中创建管道,并返回两个文件描述符,一个读取一个写入
-
管道命令处理:
cmd1 | cmd2
-
管道写进程和管道读进程连接起来:查看是否有|符号 执行代码重定向
-
命名管道:FIFO
代码实现
- fork()演示
#include <stdio.h>
#include <unistd.h>
int main()
{
int pid;
printf("this is %d, my parent=%d\n", getpid(), getppid());
pid = fork();
if (pid) {
printf("this is process %d, child pid=%d\n", getpid(), pid);
} else {
printf("this is process %d, parent=%d\n", getpid(), getppid());
}
return 0;
}
- 打印环境变量
#include <stdio.h>
#include <stdlib.h>
// 声明全局变量environ,用于访问环境变量
extern char** environ;
int main(int argc, char* argv[]) {
int i;
char* env;
// 打印命令行参数
printf("Command Line Arguments:\n");
for (i = 0; i < argc; i++) {
printf("%s\n", argv[i]);
}
// 打印环境变量
printf("\nEnvironment Variables:\n");
while (*environ) {
printf("%s\n", *environ);
environ++;
}
return 0;
}
苏格拉底提问
- 进程
- 管道
问题与解决方案
-
问题1:书上演示fork()的代码无法执行
-
问题解决方案:询问了chatgpt,找到了解决方案