qidao123.com ToB IT社区-企服评测·应用市场
标题:
【Linux】进程 | 控制块pcb | task_struct | 创建子进程fork
[打印本页]
作者:
耶耶耶耶耶
时间:
2026-2-27 09:04
标题:
【Linux】进程 | 控制块pcb | task_struct | 创建子进程fork
目次
Ⅰ. 进程的概念(Process)
1. 什么是进程?
2. 多进程管理
3. 进程控制块(PCB)
task_struct 的结构
Ⅱ. 进程查察与管理
1. 利用指令查察进程
编辑
2. /proc 查察进程信息
编辑
3. 获取进程 ID
4. 创建子进程
编辑
缘故原由:fork()的 机制
总结
文章手稿:
xmind:
文章手稿可见文末
内容:明白“进程”的概念及其在利用体系中的管理,并探究进程控制块 (PCB) 的紧张性及其结构。本文还将先容怎样查察和管理进程,以及怎样通过体系调用创建进程。
Ⅰ. 进程的概念(Process)
1. 什么是进程?
进程是一个运行中的步调。当可实行文件被加载到内存中时,该步调就成为了一个进程。
2. 多进程管理
利用体系中大概同时存在大量的进程吗?of course
利用体系必要管理这些进程,以确保体系资源(如CPU时间、内存等)公道分配。管理进程的本质是对进程数据的管理。
我们必要
先形貌再构造。
(上一章我们讲过)
以是,当一个步调加载到内存时,利用体系做的不但仅只是把代码和数据参加到内存,
还要管理进程,创建对应的数据结构。
Linux 利用体系的内核是 C 语言写的,形貌时就用到struct啦
3. 进程控制块(PCB)
在利用体系中,用于形貌进程的结构体称为进程控制块(PCB)。在Linux中,这种结构体称为 task_struct。
task_struct 的结构
struct task_struct {
volatile long state;
void *stack;
atomic_t usage;
unsigned int flags;
unsigned int ptrace;
unsigned long ptrace_message;
siginfo_t *last_siginfo;
int lock_depth;
// ... 其他属性
};
复制代码
task_struct 包罗进程的全部属性数据,如进程状态、优先级、步调计数器、内存指针、上下文数据、I/O状态信息和记账信息等。
利用体系对进程的管理,终极变成了对链表的增删查改。
什么是进程?现在为止我们可以总结成:
进程 = 可实行步调 + 该进程对应的内核数据结构
利用体系不信赖托何人的,不会直接袒露自己的任何数据结构,代码逻辑,其他数据干系的细节。
想做体系是通过
体系调用
的方式,对外提供接口服务的。
下面我们未来学习一些体系接口
Ⅱ. 进程查察与管理
1. 利用指令查察进程
运行
通过下面这些下令,可以方便地查察和管理体系中的进程。
指令寄义ps a表现现行终端机下的全部步调,包罗其他用户的步调ps -A表现全部步调ps c列出步调时,表现每个步调真正的指令名称ps -e表现全部步调ps e列出步调时,表现每个步调所利用的环境变量ps f用ASCII字符表现树状结构,表达步调间的相互关系ps -H表现树状结构,表现步调间的相互关系ps -N表现全部的步调,除了实行ps指令终端机下的步调之外ps s接纳步调信号的格式表现步调状态ps S列出步调时,包罗已停止的子步调资料ps -t <终端机编号>指定终端机编号,并列出该终端机的步调状态ps u以用户为主的格式来表现步调状态ps x表现全部步调,不以终端机来区分ps -l表现具体PID信息通过指令如 ps 和 top 可以查察体系中的进程信息。比方,利用 ps aux 可以表现体系中全部的进程:
$ ps aux
复制代码
若需查察特定进程,可以利用 grep 过滤:
$ ps aux
| grep 'mytest' | grep -v grep
复制代码
相当于Windows 下的任务管理器:
2. /proc 查察进程信息
/proc 是一个假造文件体系,包罗当前体系的及时进程信息。
$ ls /proc
复制代码
左边蓝色的就是pid
3. 获取进程 ID
每一个进程在体系中,都会存在一个惟一的标识符--pid
我们可以实行在proc 目次下找到这个 pid ,发现这个18705 目次
ctrl+c 可以发现进程具有及时性
接下来我们重启来继承研究一下
文件的创建和存储
对代码举行一些改写
#include <stdio.h>
#include <unistd.h>
int main(void) {
FILE* fp = fopen("log.txt", "w"); // 若不存在就创建之
while (1) {
printf("I am m a process!\n");
sleep(1);
}
}
复制代码
C语言专栏中讲到过,fopen 背面如果不带路径,那么会默认在当前路径。
所谓的当前路径,其本质 ——
当进步程所在的路径
进程会自己维护,进程会知道自己的工作路径在那里:
exe
:指出进程对应的可实行步调的磁盘文件
cwd
:指出进程当前的工作路径
可以通过 getpid() 和 getppid() 体系调用获取当进步程和父进程的 ID。
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main(void) {
printf("PID: %d, PPID: %d\n", getpid(), getppid());
return 0;
}
复制代码
运行可以看到:
除了ctrl+c ,我们还可以这么制止进程
$ kill -9 [pid] # 给这个进程发送9号信号
复制代码
上面看到的ppid 我们也可以来测试一下
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main(void) {
while (1) {
printf("I am m a process! , pid: %d, ppid: %d\n",getpid(), getppid());
sleep(1);
}
}
复制代码
4. 创建子进程
通过 fork() 体系调用可以创建子进程。fork() 有两个返回值:父进程返回子进程的 PID,子进程返回 0。
为什么可以返回两个值呢?
我们可以来测试一下
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main(void) {
pid_t id = fork();
if (id == 0) {
// 子进程
while (1) {
printf("我是子进程,我的pid: %d,我的父进程是 %d\n", getpid(), getppid());
sleep(1);
}
} else {
// 父进程
while (1) {
printf("我是父进程,我的pid: %d,我的父进程是 %d\n", getpid(), getppid());
sleep(1);
}
}
}
复制代码
缘故原由:fork()的 机制
fork() 后,父进程和子进程会共享代码,数据则各自独立
。通过差别的返回值,可以让父进程和子进程区分差别的实行流,实行差别的代码块。
具体是怎么区分的可见文末手稿中的图解~
总结
进程是利用体系中非常紧张的概念。通过进程控制块(PCB)对进程举行形貌和管理是利用体系的一项紧张职责。通过利用各种工具和体系调用,我们可以方便地查察和管理进程,从而确保体系资源的有用利用。
文章手稿:
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金
欢迎光临 qidao123.com ToB IT社区-企服评测·应用市场 (https://dis.qidao123.com/)
Powered by Discuz! X3.5