进程概念
书本上的概念定义进程是程序的一个执行实例,正在执行的程序等
我们用PCB (process control block) , 进程控制块来描述一个进程, 它是一个进程描述符, 通过这个描述实现对一个程序运行的调度管理, Linux下pcb是一个task_struct结构体
task_struct是Linux内核的一种数据结构, 它被装载到RAM(内存)里并且包含着进程的信息
task_ struct内容分类: 内存指针, 程序计数器, 上下文数据, 进程标识符PID, 进程状态, 优先级, I/O信息, 记账信息等等
获取进程标识符:
进程id(PID)
父进程id(PPID)
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
printf("pid: %d\n", getpid());
printf("ppid: %d\n", getppid());
return 0;
}
进程创建:
通过复制调用进程完成一个新的子进程的创建, 创建出来的子进程运行的代码以及当前的运行位置都是和父进程一样的, 父子进程代码共享,数据独有
pid_t fork(void);
返回值: 对于父进程返回子进程的pid, 对于子进程返回0, 发生错误则返回-1
可以根据返回值对父子进程进行代码分流
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
int ret = fork();
if(ret < 0)
{
perror("fork error"); //打印错误信息
return -1;
}
else if(ret == 0)
{
//这是子进程
printf("I am child process: %d, ret: %d\n", getpid(), ret);
}
else
{
//这是父进程
printf("I am father process: %d, ret: %d\n", getpid(), ret);
}
sleep(1);
return 0;
}
查看进程常用的指令有:
ps -ef ps -aux
Linux下的进程状态
就绪/运行状态 R: 并不意味着进程一定在运行中, 它表明进程要么是在运行中要么在运行队列
睡眠状态 S: 意味着进程在等待事件完成, 有时候也叫做可中断睡眠
磁盘休眠状态 D: 有时候也叫不可中断睡眠状态, 在这个状态的进程通常会等待IO的结束
停止状态 T: 停止运行, 什么都不做
僵死状态 Z:进程已经退出了但是资源没有完全被释放的一种状态
下面要说几种特殊的进程
僵尸进程: 处于僵死状态的进程, 指的是进程已经退出不再运行, 但是资源没有完全释放的情况
僵尸进程如何产生??
子进程先于父进程退出, 并且父进程没有读取到子进程的退出码时就会产生僵尸进程
僵尸进程的危害: 资源泄漏, 一个用户所能创建的进程数量是有限的(ulimit -a查看), 并且资源没有完全回收会占据内存资源
孤儿进程: 父进程先退出, 子进程就称为 “孤儿进程” , 孤儿进程是不会成为僵尸进程的, 孤儿进程会被1号init进程领养
守护进程: 也叫精灵进程, 是一种特殊的孤儿进程, 父进程是1号进程, 运行在后台, 与终端以及登录会话脱离关系, 不再受影响, 守护进程通常是一种运行在系统后台的批处理程序
环境变量
基本概念: 环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数
环境变量的好处: 使系统运行环境配置更加简单灵活, 可以通过设置环境变量给一个进程传递参数信息
常见环境变量
PATH: 指定命令的搜索路径
HOME: 指定用户的主工作目录(即用户登陆到Linux系统中时默认的目录)
SHELL: 当前Shell,它的值通常是/bin/bash
和环境变量相关的命令
1.echo: 显示某个环境变量值 echo $[环境变量名]
2.export: 设置一个新的环境变量
3.env: 显示所有环境变量
4.unset: 清除环境变量
5.set: 显示本地定义的shell变量和环境变量
通过代码如何获取环境变量
#include <stdio.h>
int main(int argc, char *argv[], char *env[])
{
int i = 0;
for(; env[i]; i++)
{
printf("%s\n", env[i]);
}
return 0;
}
int main(int argc, char* argv[ ], char* env[ ])
main函数的第三个参数env保存环境变量
通过第三方变量environ获取
#include <stdio.h>
int main(int argc, char *argv[])
{
extern char **environ; //environ没有包含在任何头文件中,所以在使用时要用extern声明
int i = 0;
for(; environ[i]; i++)
{
printf("%s\n", environ[i]);
}
return 0;
}
通过系统调用获取或设置环境变量
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("%s\n", getenv("PATH"));
return 0;
}
char* getenv(char* name); 通过环境变量名称获取一个指定环境变量的数据
环境变量通常具有全局属性, 子进程也拥有父进程的环境变量, 子进程可以将其继承下去