【linux】进程(一)

先看预备知识,对本篇文章更有帮助。

目录

进程概念:

  • 课本概念:程序的一个执行实例,正在执行的程序等
  • 内核观点:担当分配系统资源(CPU时间,内存)的实体。

当然,课本上的概念不够我们继续深入理解。

但是内核观点又太过专业。

我们先来看下边的这张图。

我们发现:进程是可以多个一起存在的。既然这样,那就意味着操作系统(operating system)是要对进程进行管理的。

管理就说明我们要对进程先描述再组织。

这也正好对应操作系统中的一个PCB的概念。

描述进程-PCB:

  • 进程信息被放在一个叫做进程控制块的内核数据结构中,可以理解为进程属性的集合。
  • 课本上称之为PCB(process control block),Linux操作系统下的PCB是: task_struct

task_ struct内容分类:

  • 标示符: 描述本进程的唯一标示符,用来区别其他进程。
  • 状态: 任务状态,退出代码,退出信号等。
  • 优先级: 相对于其他进程的优先级。
  • 程序计数器: 程序中即将被执行的下一条指令的地址。
  • 内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
  • 上下文数据: 进程执行时处理器的寄存器中的数据休学例子,要加图CPU,寄存器。
  • I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
  • 记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
  • 其他信息

那么PCB就是我们的进程吗?

答案是否定的,回忆一下我们在冯诺依曼体系中说到的,代码和数据会先加载到内存,再由操作系统创造出相应的PCB

故 进程 = PCB+代码和数据

了解动态运行的概念:

进程的本身内部属性:

进程的本身属性有什么?

那我们需要先启动一个进程

启动进程:

cpp 复制代码
int main()
{
    while(1)
    {
        //printf("I am a process, pid:%d\n", getpid());
    }
    return 0;
}

在利用ps -ajx命令进行查看进程

我们发现其中有多个属性 :

PID(进程ID) PPID(进程父ID) STAT(进程状态)等
PID就是我们每个进程的唯一标识符!

那么我们除了使用命令查看还可以使用什么查看我们的PID呢?

使用getpid函数(系统调用接口)即可查看

代码样例:

代码运行结果:

关闭进程:

直接kill -9 pid即可

也可以使用ctrl + c。

如何创建进程:

了解了进程,那么如何创建呢?

其实我们每运行一个程序就相当于创建了一个进程。

如何在代码内创建呢?
fork函数

代码样例:

运行结果:

进程状态:

直接看进程状态:

为了弄明白正在运行的进程是什么意思,我们需要知道进程的不同状态。一个进程可以有几个状态(在Linux内核里,进程有时候也叫做任务)。

下面的状态在kernel源代码里定义:

cpp 复制代码
/*
* The task state array is a strange "bitmap" of
* reasons to sleep. Thus "running" is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};
  • R运行状态(running): 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。

  • S睡眠状态(sleeping): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠(interruptible sleep))。

  • D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。

  • T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。

  • X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态。

僵尸进程与孤儿进程:

僵死状态 (Zombies)是一个比较特殊的状态。当进程退出并且父进程(使用wait()系统调用,后面讲)

没有读取到子进程退出的返回代码时就会产生僵死(尸)进程

僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。

所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态

僵尸状态危害:

进程的退出状态必须被维持下去,因为他要告诉关心它的进程(父进程),你交给我的任务,我办的怎么样了。可父进程如果一直不读取,那子进程就一直处于Z状态?是的!

维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话说,Z状态一直不退出,PCB一直都要维护?是的!

那一个父进程创建了很多子进程,就是不回收,是不是就会造成内存资源的浪费?是的!因为数据结构对象本身就要占用内存,想想C中定义一个结构体变量(对象),是要在内存的某个位置进行开辟空间!

内存泄漏?是的!


父进程如果提前退出,那么子进程后退出,进入Z之后,那该如何处理呢?

父进程先退出,子进程就称之为"孤儿进程 "

孤儿进程被1号init进程领养,当然要有init进程回收喽。

相关推荐
且从容.8 小时前
ubuntu安装flink
linux·ubuntu·flink
数字新视界9 小时前
动环监控信创适配在智能机房管理中的应用价值与未来展望
大数据·服务器·数据库·动环监控系统·动力与环境监控系统
爱和冰阔落9 小时前
【Linux网络】TCP 服务器如何并发处理多个客户端?从 fork、僵尸进程到双重 fork
linux·运维·服务器·网络
程序员沉梦听雨9 小时前
WSL2的安装与使用
linux·wsl
微小的鱼10 小时前
Linux的渲染与显示系统链路
android·java·linux
lisanmengmeng10 小时前
alertmanger 标签 rules 打上分组标签
linux·运维·服务器
Android系统攻城狮11 小时前
Linux FFmpeg深度解析之av_write_frame调用流程与实战(三十三)
linux·运维·服务器·ffmpeg·音视频进阶·ffmpeg音视频
上火的金鱼妹11 小时前
k8s生产实际问题排查(网关,数据库读写等)
运维·服务器
孙克旭_11 小时前
k8s基础组件与创建资源
运维·docker·容器·kubernetes
孙克旭_11 小时前
云原生基础之Containerd容器运行时
运维·云原生