[ linux-系统 ] 进程概念与基本操作

1.进程的概念

1. 什么是进程?

进程是一个运行中的程序。当可执行文件被加载到内存中时,该程序就成为了一个进程。

2. 多进程管理

操作系统中可能同时存在大量的进程吗?当然可以

操作系统需要管理这些进程,以确保系统资源(如CPU时间、内存等)合理分配管理进程的本质是对进程数据的管理。

我们需要 先描述再组织。

所以,当一个程序加载到内存时,操作系统做的不仅仅只是把代码和数据加入到内存,

还要管理进程,创建对应的数据结构。

Linux 操作系统的内核是 C 语言写的,描述时就用到struct

2.描述进程--PCB

在操作系统中,用于描述进程的结构体称为进程控制块PCB(process control block)。在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状态信息和记账信息等。 

操作系统对进程的管理,最终变成了对链表的增删查改。

什么是进程?目前为止我们可以总结成:进程 = 可执行程序 + 该进程对应的内核数据结构

操作系统不相信任何人的,不会直接暴露自己的任何数据结构,代码逻辑,其他数据相关的细节。

想做系统是通过 系统调用 的方式,对外提供接口服务的。

下面我们将来学习一些系统接口

3. 进程查看与管理

1.使用指令查看进程

先创建一个死循环进行测试

 在另一个终端输入以下指令,可以看到进行中的程序./myproc

按ctrl + c结束程序,再输入指令发现进程也结束了,看不到./myproc 

 

通过指令如 ps 和 top 可以查看系统中的进程信息。例如,使用 ps aux 可以显示系统中所有的进程

若需查看特定进程,可以使用 grep 过滤:

2.通过系统调用获取进程标示符

 系统调用getpid(),返回当前进程ID

杀掉一个进程还可以用kill命令 kill -9 + 进程ID

/proc 查看进程信息 

 在 Linux 系统中,/proc 是一个非常重要的伪文件系统(内存级别),不是磁盘文件,也被叫做 “进程文件系统”。它的作用是提供内核数据结构的接口,让用户可以通过文件的形式访问系统进程和内核的信息,而不需要直接与内核进行交互

如下图,我们运行myproc.c,在proc目录里就创建了一个文件夹,名字就是./myproc的进程ID

文件夹里记录这myproc的所有进程信息

在 Linux 系统中,当这个程序已经运行起来的时候,删掉可执行程序,依然可以继续运行,因为已经被加载到内存中 

exe:通过这个链接,能够确定进程当前运行的是哪个程序。(指出进程对应的可执行程序的磁盘文件)

cwd: 当前工作目录(指出进程当前的工作路径)

理解CWD(理解当前路径)

CWD(Current Working Directory)是一个指向进程当前工作目录的符号链接。通过该链接可以确定进程当前正在操作的目录路径。

看以下代码,我们在学习C语言时,文件创建fopen后面如果不带路径,就在默认路径下创建

所谓的当前路径是什么呢?其实是当前进程所在的路径(CWD)

进程会自己维护,进程会知道自己的工作路径在哪里

 可以通过chdir改变当前工作路径

3.ppid

在linux系统中,启动之后,新创建任何进程的时候,都是由自己的父进程创建的!

系统调用getppid获取父进程,发现ppid不变,我们的程序myproc是由-bash创建的

bash是Linux系统中最常用的命令行解释器(shell)所以我们在命令行中创建的进程都是bash做的(命令行中,执行程序/命令,本质是bash的进程,创建子进程,由子进程执行我们的代码)

 4.使用系统调用,创建进程

fork创建子进程

运行以下代码,发现fork()之后,printf打印了两次

说明有两个执行流,父进程和子进程

 

 执行以下代码,看fork函数的返回值:

  • 返回值决定当前执行环境:
    • 子进程:返回 0
    • 父进程:返回子进程的 PID(正整数)
    • 失败:返回 -1(如内存不足或进程数达到上限)

 上面代码if和else if 为什么会同时成立?

原因:fork()的 机制

fork() -> 两个进程 -> 父子关系 -> 一般而言,代码父子共享,但是数据各自私有一份

我们的程序myproc.c第一次从磁盘加载到内存,操作系统为它创建PCB , 当代码执行到fork()时,

为什么代码共享?因为子进程并没有二次加载

新创建进程,操作系统也要为它创建PCB,父进程和子进程的区别在于父进程从磁盘中加载代码和数据,新创建的子进程并没有从磁盘中加载代码和数据,而进程=内核数据结构+代码和数据,子进程只有内核数据结构,子进程从父进程中加载代码和数据,子进程和父进程共享一份代码

验证数据各自私有

先看以下代码对于同一份全局变量,父进程只读不做修改,子进程做修改,观察结果

父进程的gval=0,子进程的gval不断变化

 说明:进程具有很强的独立性,多个进程之间,运行时,互不影响,即便是父子进程

返回的本质,就是向指定变量进行写入返回值数据

打印的本质,就是读取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值