操作系统——进程

进程概念

通俗来讲,进程是操作系统为了管理要运行程序的东西。

首先,我们要知道操作系统是干什么的。操作系统对下要管理好软硬件资源,对上提供一个良好的运行环境。

那么OS是如何管理的?首先,对于要管理的对象,建立一个struct结构体(操作系统使用C语言写的),这个结构体可以存储对象的各种属性;然后将各个结构体放到相应功能的数据结构中,由此,对对象的管理就变为了对数据结构的增删改查。

回到进程,当程序要运行时,OS会为程序创建对应的PCB结构体(存储了程序的各种信息),将PCB以及程序的数据和代码加载到内存,根据进程状态,放到对应的队列。例如,当前程序处于运行状态,就会放到运行队列。进程就是程序的代码和数据+对应的PCB数据结构组成的。

此外,不仅是进程,操作系统对其他对象进行管理也是一样,先为对象创建可以描述属性的结构体,然后放到一个数据结构组织起来。

如何查看进程

1.通过/proc系统文件查看,文件内有进程的各种属性

例如:   ls /proc/1        查看PID为1的进程

2.通过ps指令

例如:  ps axj | head -1 && ps axj | grep Proc | grep -v grep        查看进程名为Proc的信息

创建子进程——fork

 fork是一个系统调用函数,用来创建子进程,通过多个执行流完成任务。子进程和父进程共用一份代码,子进程数据使用写时拷贝,即子进程数据在创建的时候和父进程相同,但是当要修改数据的时候,子进程数据会再复制一份数据。

函数无参,返回值pid_t是用有符号整形封装的。

函数返回值,如果创建成功,父进程就返回子进程的pid,子进程返回0,如果创建失败就返回-1

 为什么父进程要返回子进程ID,子进程返回0?

因为父进程要对子进程操作时,如果没有返回值就找不到子进程;而子进程可以通过getpid()和getppid()获取自己进程ID和父进程ID。

为什么一个函数有两个返回值?
fork函数内部会创建并调度子进程,然后返回一个值,因为父子进程共享代码,return也会被执行两次,就会有两个返回值

进程状态

R运行状态(running): 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。


S睡眠状态(sleeping): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠
(interruptible sleep))。

当进程在等待资源时会进入,例如程序要获取输入,用户还未输入时

int main()
{                                                                  
   int n;
   scanf("%d", &n);
   return 0;
}


D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。

当一个进程向磁盘写入数据时,在写入的这段时间内,进程就处于D状态,操作系统也无法杀掉该进程


T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。


X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态。

Z僵尸状态(zombie):如果子进程结束父进程还在运行,子进程不能直接销毁,对应的PCB还会存在,这是为了告知父进程其执行情况进程状态,此时子进程就处于僵尸状态。

僵尸进程也是内存泄漏,内存中不能有太多僵尸进程,只要出现操作系统可能就要崩溃了。

此外,如果父进程先结束了,子进程的PPID就会变为1,这样的进程称为孤儿进程

用top命令看到PID为1的 

 进程优先级

ps -l  查看进程信息

UID : 代表执行者的身份
PID : 代表这个进程的代号
PPID :代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号
PRI :代表这个进程可被执行的优先级,其值越小越早被执行
NI :代表这个进程的nice值

进程优先级是nice值和priority的加和,可以通过修改nice值来控制优先级

如何修改呢?

命令行输入top,输入r,然后输入进程pid,输入nice值

当我们再次修改nice值时,新的PRI会从默认值80计算,nice值的范围是-20~19

环境变量

环境变量是一种用来存储系统配置信息的机制。环境变量包含了一些系统运行时需要的参数和信息,例如文件路径、用户权限、语言设定等等。

常见的环境变量

PATH : 指定命令的搜索路径

在shell输入命令,实际上就是运行一个进程,为什么我们自己写的进程就不可以直接使用呢?

因为PATH里有shell命令的路径,会自动在这些路径中查找,只要我们把自己的程序路径放到PATH中也可以直接使用,例如

HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
SHELL : 当前Shell,它的值通常是/bin/bash

环境变量相关指令

echo $name:查看环境变量name的内容

export name=123:设置一个 新的环境变量name并赋值

 env:查看所有环境变量

 unset name :删除环境变量

set  显示本地变量和环境变量

本地变量和内建命令

环境变量实际就是一种全局变量,它可以被子进程继承;本地变量只能在本进程使用

下面给出验证:

 

 设置成bash的本地变量时,子进程不能获取;当设置为环境变量就可以了

那为什么echo就可以获取本地变量呢?echo难道不是bash的子进程吗?

是的,echo是bash的内建命令。例如pwd,cd等这些命令,都是内建命令。它们本质类似于bash自己定义的函数。试想,cd如果是子进程,那么改变的路径也是子进程的路径,bash本身的路径也没有变,所以这些命令只能写成内建命令。 

进程获取环境变量——main函数传参/直接声明

main函数的前两个参数——命令行参数

argc表示接收命令行参数的个数,argv是存储命令的数组,每个命令都是一个字符串

ls -a -l 就是三个命令行参数,argv[0] = ls argv[1] = -a argv[2] = -l

 

main函数第三个参数

 第三方变量environ获取

libc中定义的全局变量environ指向环境变量表,environ没有包含在任何头文件中,所以在使用时 要用extern声明 

getenv通过环境变量名查看

putenv在代码中添加新的环境变量

  • 10
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值