进程概念
-
进程是什么?
用户角度:正在运行的程序
操作系统角度:进程是操作系统对运行中的程序的描述信息-进程描述符-统称PCB
***当你要运行一个程序,操作系统知道了你要运行这个程序,它会创建一个PCB,将这个程序加载到内存中,用内存指针将PCB与你内存里面的数据连接起来.说白了PCB就是一个指针,保存的是你要运行的程序数据的地址.同时pcb也是一个进程存在的唯一标识***
Linux下PCB的具体对象是一个结构体-----struct task_struct
那么在struct task_struct里面到底存储了哪些信息呢 ?
描述信息 | 含义 |
进程标识符(PID) | 进程的ID , 也是唯一标识符 , 区别进程. |
进程状态 | 进程任务所处于的状态 , 比如僵尸态 , 运行态 , 死亡态等等 |
优先级 | 决定进程CPU资源的优先分配权,让操作系统运行的更加合理 |
程序计算器 | 程序中将要被执行的下一条指令的地址 |
内存指针 | 代码和相关数据的指针,还有共享内存块的指针 |
上下文数据 | 进程执行时处理器的寄存器中的数据 |
I/O状态信息 | 现实的I/O请求和分配给进程的I/O设备和被进程使用的文件列表 |
记账信息 | 包括处理时间总和,使用的时钟数总和,时间限制等等 |
其它 |
以上就是task_struct结构体里面存储的信息 , 以及各个字段的含义
-
查看进程
1. ps aux
以BSD风格显示进程
其实还有一种查看的就是ps -aux, 但是x是打印用户x的进程, 但是如果用户x不存在, 就会自动转换成ps aux, 所以我们就直接使用ps aux就可以了。
2. ps -ef
以system V 风格显示进程
推荐使用ps -ef
-
创建进程
进程创建 : fork();
实质 : 通过复制调用进程(pcb),创建一个新的进程(子进程) , 复制的是父进程的pcb,因此代码相同,数据独有,运行位置一样(常见成功的下一步指令)
返回值 : 通过返回值对父子进程进行分流
1. 对于父进程,返回的是子进程的pid > 0
2. 对于子进程,返回的是0
-
进程状态
Linux下进程状态有以下这些 :
运行态(R) , 可中断睡眠态(S) , 不可中断睡眠状态(D) , 停止态(T) , 追踪态(t) , 死亡态(X) , 僵死态(Z) .
比较重要的两个进程 :
1. 僵尸进程 : 处于僵死状态的进程(kill杀不死)
产生原因 : 子进程先于父进程退出 , 退出原因保存在pcb中 , 操作系统检测到进程退出后 , 通知父进程 , 但是父进程可能并没有关注子进程的退出 , 这时候操作系统不能随意释放子进程资源(因为父进程会关心子进程退出原因), 因此子进程就处于退出但是资源没有完全释放的状态(僵死状态)
存在危害 : 资源泄漏,僵尸进程过多,导致新进程无法创建
解决方法 : 干掉父进程(退出原因的保存已经毫无意义)
避免方法 : 进程等待
僵尸进程实现 :
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
printf("!!僵尸进程!!\n");
int pid = fork(); //创建一个子进程
if(pid == 0)
{
sleep(5);//五秒钟后退出子进程
exit(0);
}
uint64_t a = 0;//8个字节(无符号长整型)
while(1)
{
a++;
usleep(1000);
}
return 0;
}
运行这个程序
五秒之后 , 我们发现进程zombie的进程状态从 S+ 变成了 Z+ , 这个时候他已经成为了一个僵尸进程
那么我们如何避免产生僵尸进程呢 ?
方法 : 子进程退出之后进程等待.
int pid = fork(); //创建一个子进程
if(pid == 0)
{
sleep(5);//五秒钟后退出子进程
exit(0);
}
wait(); //在此处进程等待
重新运行
五秒之后 , 并没有出现僵尸进程 , 子进程退出 , 父进程依然运行
2. 孤儿进程 : 父进程先于子进程退出 , 子进程成为孤儿进程 , 被init进程收养 , 到后台运行.
测试用例 :
#include <stdio.h>
#include <unistd.h>
int main()
{
fork();
while(1)
{
sleep(1);
}
return 0;
}
运行程序 , 可以看到 , 父进程子进程正常运行
我们杀死父进程 , 使其子进程成为孤儿进程
可以看到 , 程序已经停止运行 , 子进程成为孤儿进程 .
环境变量
概念
环境变量其实就是存有操作系统运行参数的变量, 使得系统设置更加方便
常见的环境变量
- PATH :指定命令的搜索路径
- HOME : 指定用户的工作目录
- SHELL : 当前shell , Linux下通常指 /bin/bash
查看环境变量
查看某一个环境变量 :
1. echo $name name : 环境变量名
2. env | grep name name同上
比如 :
查看所有环境变量 :
1. env
2. set set的意思是查看所有本地变量(包括环境变量)
设置环境变量
export : 设置环境变量
比如 : export abc=10
通过代码获取环境变量
1. 命令行第三个参数
#include <stdio.h>
int main(int argc, char* argv[], char* env[])
{
int i = 0;
for(;env[i];i++)
{
printf("env[%d]----[%s]\n",i.env[i]);
}
return 0;
}
2. 通过第三方变量environ
extern : 修改链接属性
environ : 是一个二级指针,不在头文件中包含,是在标准库stdlib中定义的一个指针变量, 里面存储的是环境变量
#include <stdio.h>
int main(int argc,char* env[])
{
extern char** environ;
int i= 0;
for(;environ[i];i++)
{
printf("%s\n",environ[i]);
}
return 0;
}
以上就是进程概念相关的一些东西 , 当然不止这些 , 后面会继续补充,如果有问题请指点, 谢谢观看^_^