20191324读书笔记6
第三章 Unix/linux进程管理
- 多任务处理指的是同时进行几项独立活动的能力
- 进程:在操作系统中,任务也称为进程,执行映像定义为包含代码、数据和堆栈的存储区,进程就是对映像的执行。
- PROC结构体:在操作系统知识中我们学习过,进程的状态用一个独特的数据结构表示,叫做进程控制块(PCB)。在Liunx中也可以称为PROC结构体。PROC结构体包含某个进程的所有信息。
点击查看PROC结构体
typedef struct proc{
struct proc *next;
int *ksp;
int pid;
int status;
int priority;
int kstack [SSIZE];
}PROC;
多任务处理系统
- 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;
- ts.s文件在32位GCC汇编代码中可实现进程上下文切换
点击查看代码
#-------------- ts.s 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|
# -1 -2 -3 -4 -5 -6 -7 -8 -9
- 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");
}
- enqueue()函数按优先级将PROC输入队列中。在优先级队列中,具有相同优先级的进程按照FIFO的顺序排序。
- dequeue()函数可返回从队列或链表中删除的第一个元素。
- printList()函数可打印链表元素。
- t.c文件定义MT系统数据结构、系统初始化代码和进程管理函数
- 睡眠模式:当进程需要某些当前没有的东西的时候,就会进入休眠状态。
- 唤醒操作:调用kwakeup()就可以唤醒一个进程。此时,正在休眠的一个程序得到了需要的资源,继续执行其操作。
- 进程终止:进程完成后,就会终止或死亡。进程会以两种方式终止:1)正常终止:进程自行调用结束函数exit(value)进行终止。2)异常终止:进程因为某个信号而异常终止。终止时,都会调用kexit()。
进程管理中的系统调用
- fork:在fork函数执行完毕后,如果创建新进程成功,则出现两个进程,一个是子进程,一个是父进程。在子进程中,fork函数返回0,在父进程中,fork返回新创建子进程的进程ID。
通过fork返回的值来判断当前进程是子进程还是父进程。 - exec:用fork函数创建子进程后,子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程执行的程序完全替换为新程序,而新程序则从其main函数开始执行。
因为调用exec并不创建新进程,所以前后的进程ID并未改变。exec只是用一个全新的程序替换了当前进程的正文、数据、堆和栈段。
SHELL:指定将解释任何用户命令的sh。
TERM:指定运行sh时要模拟的终端类型。
USER:当前登录用户。
PATH:系统在查找命令时将检查的目录列表。
HOME:用户的主目录。在 Linux 中,所有用户主目录都在/home中。
环境变量
各环境变量定义为:关键字=字符串
点击查看代码
*#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[] );*
I/O重定向
- sh进程有三个用于终端I/O的文件流:stdin(标准输入)、stdout(标准输出)、stderr(标准错误)。其文件描述符分别对应0、1、2。
管道 |
- 管道是用于进程交换数据的单向进程件通信通道。管道有一个读取端和一个写入端。
- 管道命令处理:在Unix/Linux中,命令行cmd1 | cmd2,sh将通过一个进程运行cmd1,并通过另一个进程运行cmd2,他们通过一个管道连接在一起,因此cmd1的输出变为cmd2的输入
- 命令管道:命令管道又叫FIFO。在sh中,通过mknod命令创建一个命令管道:
mknod mypipe p
或在c语言中发出mknod()系统调用
int r = mknod("mypipe",s_IFIFP,0);
进程可像访问普通文件一样发个文命名管道。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~