Linux操作系统中进程,PCB,fork()函数,僵尸进程,孤儿进程,进程优先级,环境变量

2019-07-14 07:35发布

操作系统(Operator System)

操作系统有很多种类,但是大的放向有三类。
Windows、MAC、Linux操作系统。
操作系统在计算机中,相当与一个管家,对下合理安排管理计算机资源,对上提供给用户一个稳定的操作环境。
计算机发展到现在经过不断的改进,目前使用的是冯诺伊曼体系结构,以内存,CPU,输入,输出。
操作系统中内核就是属于内存管理进程管理等,在操作系统中为了管理完成一些任务,或者说作业,那么就会通过描述一个任务,然后进行管理。 计算机实现图

进程

概念
是一个程序执行的一个实例,程序正在执行。
从内核来看,是分配系统资源的实体。
描述(PCB)
那么怎么来描述一个进程呢?
进程的描述是通过PCB来进行描述。在Linux中描述PCB是通过一个叫task_struct的结构体。PCB中有什么呢?
有这么几个:
1. 标识符:用来描述本进程的唯一标识符,区别其他进程
2. 状态:用来表示当前进程的状态,退出码,退出信号
3. 优先级:相对于其他进程之间的优先级
4. 程序计数器:用于记录程序的下一条指令的地址
5. 内存指针:其中有代码和数据相关的指针,还有共享内存块指针
6. 上下文:进程执行时寄存器中的数据
7. I/O状态
8. 记账信息:其中包含各种时间
9. 其他
这里重点说明一下进程的状态:
进程的状态有: 1.R:运行状态。表示的是进程在就绪队列或者正在运行。这个是不定。
2.S:睡眠状态。表示进程在等在某件事情完成。
3.D:磁盘休眠。不可中断睡眠。
4.T:停止状态。用来停止该进程。用kill 查看对应的编号
5.X:死亡状态。进程结束。
6.Z:僵尸状态。既进程结束但是PCB为释放

fork()函数

fork函数用来创建一个进程。这个函数是一个很特别的系统函数,怎么特别呢?
因为它调用一次有两个返回值。 fork 返回值类型是pid_t类型。其实就是一个int型,经过封装后为pid_t类型。
而且fork函数在创建出子进程时,父子进程代码共享,数据各自开辟空间,私有一份,并且采用写时拷贝。 fork函数返回两个值,那么我们怎么进行操作呢?
fork函数是创建出一个子进程,那么我们可以用if语句来进行分流。在分流前,我们要了解到,fork出来的子进程返回值为0,而父进程的返回值为子进程的pid。所以我我们就可以用以下代码进行分流 int main() { pid_t ret = fork(); if (ret > 0) { // 父 } else if (ret == 0) { // 子 } else { perror(); }
我们来总结一下fork函数:
1. 一次调用有两个返回值,父进程返回子进程的pid,子进程返回0
2. 父进程和子进程都从fork执行结束之后的位置继续执行
3. 子进程以父进程为模板。采用写时拷贝
4. 父子进程执行的先后顺序,不确定,取决于操作系统调度器
fork()函数创建子进程失败情况
1)创建进程数达到上限
2)内存满了,不能有空间进行进程的创建。

僵尸进程

什么是僵尸进程?
在这里因为要说明,僵尸进程也是进程的一个状态,是Z状态(zombie)。
怎么才能进入Z状态,也就是怎么产生的僵尸进程。
僵尸进程的产生是因为在子进程在做完父进程分配好的任务,需要父进程来接受子进程的返回码,但是父进程没有接受,这样子进程就会形成僵尸进程,会以进程终止在进程表中,PCB还在占用系统资源。
如果父进程还在运行,子进程进入Z状态,并且占用系统资源。
产生僵尸进程代码: #include #include #include int main() { pid_t id = fork(); if (id > 0) { // 父进程 printf("%d ", gitpid()); sleep(10); } else if (id == 0) { // 子进程 printf("%d ", gitpid()); sleep(5); } else { perror("fork"); } return 0; } 僵尸进程

孤儿进程

什么是孤儿进程?
孤儿进程简单的说:
就是当父进程创建出子进程,但是是父进程先退出,子进程还没退出,就形成了孤儿进程。
如果形成孤儿进程怎么处理,如果出现孤儿进程,那么就会由1号进程收养,该进程的父进程变成1好进程Init进程。init进程会每隔一会wait(),直到收回孤儿进程结果,让孤儿进程正常退出。
用代码演示孤儿进程: #include #include #include int main() { pid_t id = fork(); if (id > 0) { printf("%d", gitpid()); sleep(1); } else if (id == 0) { printf("%d ", gitpid(), gitppid()); sleep(10); } else { perror("fork"); } return 0; } 孤儿进程

进程优先级

进程优先级是干什么用的。为什么会有进程优先级。
进程优先级就决定了,进程执行的先后顺序,也就是为了合理的按照一定顺序分配系统资源。
对于一个多任务系统,这样做大大的改善了系统的整体性能。
怎么查看Linux下的进程:ps -l
进程
需要知道:
UID:代表执行者的身份
PID:代表进程的唯一标识符
PPID:代表当前进程的父进程。
PRTI:代表进程被执行的优先级,值越小越被先执行
NI:代表进程的NICE值。(nice值也可以叫修正数)
关于优先级,难道就只能按照系统给出的执行吗?自己不可以修改吗?
不!
我们可以通过修改NICE值进行修改优先级。但是nice值是有修正范围的是-20到19,四十个级别。
具体怎么调整:
调整的规则是 新优先级 = 旧有限级 + nice值
1)程序启动前调整:nice -n -5 ./a.out
2)调整已经存在的进程优先级:renice -5 -p PID号 (意思是把进程号的nice值修改为-5)
3)用top命令修改nice值:进入top后按r输入PID号再输入nice值
最后再总结一下进程的四个性质
竞争性:进程数量较多,而cpu等资源少,就会形成进程间的竞争。合理的竞争会高效的完成任务。也因此有了优先级
独立性:多进程运行,有着自己独有的资源,进程与进程之间不会收到影响。
并发性:并发从宏观上看是同是运行,其实在微观上看系统的进程是串行运行,因为CPU的速度比较快,所以就看上去是同时运行。
并行性:并行就是同时运行多个 进程,这是因为有多个cpu处理器,达到了同时处理两个进程或者多个进程。就形成了并行。

Linux下的环境变量

环境变量:一般是指在操作系统中用来指定操作系统运行环境的一些参数。
如:我们在编译代码链接库时,没有关心库在哪?这个就是环境变量在帮助编译器查找。

常见环境变量

  1. PATH:命令搜索路径
  2. HOME:指定用户的主工作目录
  3. HISTSIZE: 保存历史命令的记录条数
  4. SHELL:当前shell,通常是/bin/bash 常用命令
    echo $name :name是环境变量名称,查看环境变量方法。
    env: 查看所有环境变量
    export:(重点)设置一个环境变量

    在linux下设置环境变量PATH值

    有三种:
    1)设置当前进程的PATH,也就是在当前终端窗口有效,如果重新打开终端又回到以前。在命令行输入 export PATH=$PATH:路径
    2)设置用户环境变量(linux是多用户多任务)设置完成就可以在改用户下是永久的。要到用户的~/.bash_profile
    添加 export PATH=$PATH:路径
    3)设置全局系统环境变量,到/etc/profile文件中添加。

    通过系统调用来获取环境变量

    getenv讲解
    可以通过代码调用系统调用来获取某个环境变量。 #include #include int main() { printf("%s ", getenv("PATH")); return 0; } 获取环境变量PATH的值
如有误,还望指正,谢谢!