Linux下进程的一些常用命令:
1、ps 列出ps命令执行那一时刻当前终端的有关进程
2、command &在一条命令后面加&,可使得command在后台运行
3、jobs显示当前后台运行的程序
4、Ctrl+z命令可以使得当前正在终端运行的命令放到后台运行,但是变为停止状态
5、bg (jobs id)使得命令由停止态变为运行态
6、kill -9 pid可以强制杀死进程
7、top命令可以实时显示当前运行的进程
进程的概念:进程是一个独立的可调度的任务是一个抽象的概念,当系统在执行某个程序时,会分配和释放各种资源,分配和释放的过程称为调度:时间片+轮转:将时间分段,每一段称为一个时间片,多个任务轮流使用cpu,但是每个任务每次最多占用cpu一个时间片。
父进程和子进程的调度是不可预期的,但是可以通过
进程是一个程序的一次执行的过程,也是程序执行和资源管理的最小单位
一个程序运行的过程叙述如下:
我们的应用程序在Linux系统上的格式是ELF格式的,其实质就是一个文件,存放在我们的硬盘上,当我们开始执行一个程序的时候,cpu会先把程序从硬盘上加载到内存中(加载的部分分为.text节,.rodata节,.data节),同时在内存中分配两块内存分别为内存地址空间和task_struct结构体,这两块区域就组成我们的进程,其中一块内存存放的是我们的命令行参数、环境变量,栈、堆以及从硬盘上加载的数据和代码;另一块内存存放的是task_struct结构体,这个结构体的成员就是描述所创建进程的详细的信息。
一个进程是一个程序的实例。
进程的状态图:
如上图所示,进程的状态分为以上几个状态。
进程就像是一个树结构,这个树的树根是init的进程,其进程pid=1
所有进程都是由这个进程直接或者间接创建的。
1、我们通过fock()函数创建一个进程a,此时a就获得了除cpu外的相应的资源,现在a的状态为就绪态(图上为运行态)
2、然后通过cpu的调度,进程a就获得了cpu资源进入运行态(图上为拥有cpu)
3、如果时间片到了那么程序就再次回到就绪态等待cpu的再次调度
4、如果a进程主动放弃cpu,那么进程a就进入等待态
这里的等待态分为可中断和不可中断,所谓可中断是相对于是否可以被信号中断,但是他们都可以被硬件中断。
5、进入等待态的进程被唤醒后就进入就绪态
6、运行态接收到SIGSTOP信号,进入暂停态,暂停态接收到SIGCONT又进入就绪态
7、当程序运行到exit()命令的时候,进程的内存就会被释放,只保存一个task_struct结构体保存进程退出的原因,此时进程就进入僵尸态。
8、当cpu将僵尸态回收之后,这个进程才是真正的结束。
有三种情况下僵尸态可以被回收:
(1)父进程调用wait()函数,回收子进程的退出状态,随后释放此进程所占用的所有资源
(2)创建子进程的之前,父进程通知内核将不会对子进程就行回收,那么内核会在子进程结束后对子进程进行回收
(3)父进程意外结束,那么内核就会将子进程托付到init进程,通过init进程进行回收。
如果父进程在创建时候没有通知内核不会回收子进程,而且内核进入了死循环,那么子进程就会变为僵尸,此时这个僵尸会永远占用这块内存,这是很危险的。
cpu有个程序状态寄存器,标示当前cpu工作在什么模式:
用户模式:访问系统资源能力是受限
内核模式:访问系统资源能力不受限
两种模式可以通过切换的
fork,exec,exit(),_exit(),wait,waitpid
其中exit()函数在终止当前进程之前,会检查该进程打开了哪些文件,并把文件缓冲区的内容写回文件(清理IO缓存)
_exit()函数会直接结束进程,清理其使用的内存空间和数据结构。
IO缓存:每次打开一个文件,都会在内存中创建一块缓冲区,读到的数据写放入缓冲区中,下次可以直接从缓冲区中读取;同样,写入的时候,也要先写入缓冲区,等满足一定条件(缓冲区被写满,或遇到特定字符),会一次性将缓冲区的内容写入文件中,这样提高了写入的效率。但是,有些数据被认为写入文件,但是实际上因为不满足特定条件,所以实际上还在缓冲区。
Linux守护进程的创建:
1、创建子进程,父进程退出
2、在子进程中创建新会话setsid()
3、改变当前目录
4、重设文件权限掩码
5、关闭文件描述符