Linux基础进程的概念及fork初识
Posted Ricky_0528
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux基础进程的概念及fork初识相关的知识,希望对你有一定的参考价值。
文章目录
1. 概念
1.1 冯诺依曼体系结构
1.2 操作系统
一款专门针对软硬件资源进行管理工作的软件
对下:管理好软硬件资源
对上:给用户提供稳定的、高效的、安全的运行环境
先描述被管理对象,再组织将被管理对象使用特性的数据结构组织起来
管理的理念:先描述,再组织
可以将对目标的管理转化成为对数据的管理
描述进程的结构体——PCB-进程控制块
1.3 系统调用与库函数
- 在开发角度,操作系统对外会表现为一个整体,但是会暴露自己的部分接口,供上层开发使用,这部分由操作系统提供的接口,叫做系统调用
- 系统调用在使用上,功能比较基础,对用户的要求相对也比较高,所以有心的开发者可以对部分系统调用进行适度封装,从而形成库,有了库就很有利于更上层用户或者开发者进行二次开发
1.4 进程基本概念
加载到内存的程序
- 程序的一个执行实例,正在执行的程序
- 内核观点:担当分配系统资源(CPU时间,内存)的实体
进程 = 程序 + 操作系统维护进程的相关数据结构
1.5 描述进程——PCB
有了进程控制块,所有的进程管理任务与进程对应的程序毫无关系,与进程对应的内核创建的该进程的PCB强相关
-
进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合
-
课本上称之为PCB(Process Control Block),Linux操作系统下的PCB是:task_struct
-
task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息
-
组织进程:所有运行在系统里的进程都以task_struct链表的形式存在内核里
struct task_struct //进程的所有属性 的内容分类
-
标示符:描述本进程的唯一标示符,用来区别其他进程
-
状态:任务状态,退出码,退出信号等
-
优先级:相对于其他进程的优先级
-
程序计数器:程序中即将被执行的下一条指令的地址
-
内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
-
上下文数据:进程执行时处理器的寄存器中的数据
上下文的保存和恢复,让我们可以感受到进程是被切换的
-
I/O状态信息:包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表
-
记账信息:可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等
2. 查看进程
查看上一次退出的进程的退出码:
echo $?
getpid、getppid
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
while (1)
printf("Hello! pid:%d ppid:%d\\n", getpid(), getppid());
sleep(1);
return 0;
getpid():获取当前进程的pid
getppid():获取当前进程父进程的pid
两个函数都需要包含系统头文件:sys/types.h
查看 “proc” 的相关进程 带上行首:
ps axj | head -1 && ps ajx | grep "proc"
ps axj | head -1 && ps ajx | grep "proc" | grep -v grep // 可以去掉最后一个
查看PID为 12761 的进程:
ps axj | grep "12761"
杀掉PID为 23627 的进程:
kill -9 23627
系统文件夹 proc 存放了进程信息(该处proc为系统文件夹,并不是我创建的.c文件及其可执行程序)
获取PID 为31348的进程信息
ls /proc
ls -al /proc/31348
exe:进程对应的可执行程序
cwd:表示当前工作目录
3. fork()
通过系统调用创建进程
3.1 基本概念
使用fork创建进程,系统里就多了一个进程,与进程相关的内核数据结构、进程的代码和数据在系统里多了一份
默认情况下,子进程会“继承”父进程的代码和数据,内核数据结构task_struct也会以父进程为模板,初始化子进程的task_struct
fork之后,子进程和父进程的代码是共享的,而代码是不可被修改的,因此父子进程并不互相影响
数据各自开辟空间,私有一份,通过“写时拷贝”来实现进程数据的独立性,只有修改才会拷贝过去
进程是具有独立性的
3.2 返回值
fork() 的返回值类型为 pid_t
通过fork的返回值来让子进程和父进程做不一样的事情
- 失败:返回值 < 0
- 成功
- 给父进程返回子进程的pid
- 给子进程返回0
#include <iostream>
#include <unistd.h>
int main()
pid_t id = fork();
if (id == 0) //子进程
//child
while (true)
std::cout << "I am child, pid: " << getpid() << ", ppid: " << getppid() << '\\n';
sleep(1);
else if (id > 0) //父进程
//parent
while (true)
std::cout << "I am child, pid: " << getpid() << ", ppid: " << getppid() << '\\n';
sleep(2);
else
return 0;
两个返回值的理解:函数执行了return表名核心功能以及执行完毕,但父子进程可以同时return
返回值也是数据,return的时候发生了写时拷贝
给父进程返回子进程的pid:让父进程达到控制子进程的目的,因为父进程与子进程是一个一对多的关系,返回子进程的pid让父进程可以进行区分,而一个子进程只有一个父进程,因此不需要知道父进程的pid
以上是关于Linux基础进程的概念及fork初识的主要内容,如果未能解决你的问题,请参考以下文章
Linux深入理解重定向inode详解与软硬链接的概念及区别