【Linux】进程

概念进程

一个已经加载到内存中的程序叫做进程(也可以叫做任务)

在Linux中使用【ps axj】可以查到正在运行的进程

在Linux中,称正在运行的程序叫做进程。

理解进程

        一个操作系统不仅仅只能运行一个进程,可以同时运行多个进程。而有的进程是刚开始运行,有的是已经运行起来,有的是已经运行结束的。所以操作系统需要将进程管理起来——>先描述再组织。


先组织再描述


        任何一个进程,在加载到内存形成真正的进程时候,操作系统会先创建描述进程(属性)的结构体对象——PCB(process ctrl block).

PCB本质:进程属性的集合(也是struct结构体)

【这个结构体的内容分类】

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

根据进程的PCB类型,为该进程创建对应的PCB对象。单独的PCB(描述该进程的对象)+该进程的代码和数据=进程。

所谓的进程,就是内核PCB数据结构对象和其代码和数据。

【解释】在将一段代码传入到内存中的时候,操作系统会将这个代码设置相对应的struct结构体对象,然后这个结构体对象中有一个指针,会指向这个代码和数据。也就是说,在内存中有这个代码的属性,和这个代码,这两个内容的和称为一个进程。

  • 操作系统在管理这个进程的时候,不需要考虑进程相关的代码和数据,只需要管理这个进程的PCB数据结构对象即可

在操作系统中,对进程进行管理,变成了对链表等数据结构进行增删查改。


Linux中是如何管理进程

  • 进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合
  • PCB(process control block),Linux操作系统下的PCB是:task_struct.
  • task_struct是Linux内核中的一种数据结构类型,它会被装载到RAM(内存)里并且包含着进程的信息。

tast_structhttps://www.cnblogs.com/tongyan2/p/5544887.html

问题:Linux是如何组织进程的?

Linux内容中,最基本的组织进程task_struct的方式,采用双向链表的方式。

查看进程

进程的信息通过 /proc 系统文件夹中查看

  • 使用指令 ls /proc

PID:进程的id值

PPID:父进程id值

  • 可以使用指令:ps axj指令查看进程信息
  • ps ajx | head -1 查看进行信息的第一行
  • ps axj | grep process 查看进行信息中包含process字样的行

#include<stdio.h>

#include<unistd.h>


int main()
{       
        while(1)
        {
                printf("process: \n");
                sleep(1);
        }
        return 0;
} 

使用vim编辑器编写这段代码。

调用man 3 sleep,在3号手册中了解到sleep()函数的头文件是#include<unistd.h>

使用./process就开始了一个进程。

调用指令ps axj | head -1 查看进程的属性头

  • 查看进程的相关属性,PID是进程的ID属性,COMMAND表示进程运行时执行的是什么指令。
  • grep会过滤后面相关的内容,而grep执行指令后自己也是一个进程,自身也携带了process关键字的
  • 如果不想出现grep这个进程,可以再在这条指令后面添加grep -v grep【grep携带-v选项,即反向选择,即显示除没有‘搜寻字符串’内容的那一行。】
  • 获取到进程的pid后,可以对这个进程进行操作了,例如:kill -9 176146——杀死这个进程

系统调用进程ID

  • 每一个进程在被创建出来的时候,都会有自己的PID,操作系统会将每一个进程的PID存放在每一个进程的结构体task_struct中。
  • ps axj这个指令是使用C语言写出的,其本质就是通过代码通过系统调用接口,然后遍历每一个进程的task_struct中的每一个属性,并将这些属性打印出来、

如何获取程序的PID?

  • 系统会给用户提供一个系统调用接口:getpid();来获取进程的pid属性——进程标识符
  • 使用系统二号手册来查看系统调用接口:man 2 getpid

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
	// pid_t is int type
	pid_t id = getpid();
	while(1)
	{
		printf("process PID: %d\n", id);
		sleep(1);
	}
	return 0;
}

  • while :; do ps axj | head -1 ; ps axj | grep process | grep -v grep; echo "---------------------------------------------"; sleep 1; done
  • 使用上述指令在一个新的会话中形成一个监控脚本,来获取进程的相关属性,这里主要为了查看进程的PID
  • 使用getpid()在自己的代码中获取进程id和使用指令ps axj获取进程属性中的pid值相等。
  • 每一次运行程序时,每一次进程id都会不同,这是操作系统在进程运行时随机分配的。

getpid(); 获取进程的id值


父进程

每一个进程都是由其父进程创建出来的


getppid(); 获取父进程的id值


#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
        // pid_t is int type
        pid_t pid = getpid();
        pid_t ppid = getppid();
        while(1)
        {
                printf("process PID: %d---Father process PID: %d\n", pid, ppid);
                sleep(1);
        }
        return 0;
}

使用系统调用和使用ps axj获取的进程id和父进程id是相同的。

运行多次实验发现,每一次的进程id都不同,而每一个父进程id都是同一个id值。

  • 而这个一直不变的父进程就是bash进程
  • 每一次登陆xshell时,操作系统都会重新创建一个bash进程,这个bash进程的pid也会改变
  • 系统创建的bash进程会在终端形成命令行解释器
  • 我们在命令行解释器下输入的所有的进程都是bash进程的子进程
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值