【Linux】操作系统与进程

外设、CPU 之间的第三者:内存

        冯诺依曼体系结构:外设只与内存交互,CPU 只与内存交互。内存有什么作用?内存具有数据存储的能力,可以预装数据。在计算机中,每一部外设与 cpu 都遵守冯诺依曼体系结构。

问:从外设到 CPU,还要经过内存,岂不是更加慢了?

答:不是的,CPU要访问 1 条数据,外设直接给内存装载 100 条数据,这样就只有装载的时候那 1 次慢,其余的 99 次都是快。由于三者之间是独立的,在 CPU拿数据的同时,外设可以往内存中装载数据,互不干扰。

结论 1:站在硬件的角度和数据层面上,CPU 和内存打交道,外设和内存打交道;

结论 2:数据需要处理,必须预装到内存中,通过操作系统完成;

结论 3:程序要运行前,必须加载到内存上,为什么?因为可执行文件是在外设当中的,外设只与内存打交道;

结论 4:寄存器不仅是 CPU 有,其他外设和内存都有,数据交互都与寄存器相关;

结论 5:各种硬件单元间链接用的都是总线(IO总线、系统总线);

结论 6:外设在加载到内存前,会发出电脉冲(控制信号)给 CPU,随后 CPU 告诉内存提取提取数据。

 操作系统的上下关系:

        操作系统是一款管理软硬件资源的软件,有进程管理、驱动管理、内存管理、文件系统。目的是为了给用户提供一个良好的执行环境。

OS 与用户之间沟通:

        因为操作系统要保障自身安全,用户不能直接访问 OS ,所以封装了许多系统调用接口,而每个接口都用库(libc)封装起来。

OS 与外设之间沟通:

        当操作系统需要拿数据时,会向驱动发送信号,而外设通过驱动转换返回给操作系统,期间操作系统和外设没有直接交往,转换数据一般通过寄存器转换。

        因为自己完成外设的成本太高(因为外设太多且升级改款),所以单独创建出驱动层,让操作系统和硬件进行解耦。大多外设厂家自己会有驱动,连接电脑时会预装到内存,断开后退出。

操作系统如何管理进程:

        什么叫进程?一个可执行程序从外设中,加载的内存上,就成为了进程,简称跑起来了。

        操作系统如何管理内存呢?当一个可执行程序加载到内存上时,会创建相对应的 进程控制块:PCB(在 Linux 中叫做 task_struct ),操作系统把每一个进程所对应的 task_struct 用链表的方式连接起来,所以说,操作系统对进程的管理,就是对链表的增删查改。

        也可以说操作系统对进程的管理是:先描述,在组织!!!操作系统先拿到数据,在描述结构体属性信息,构建 PCB ,进而对 PCB 进行管理。

查看进程代码:

ps aux | head -1 && grep -v grep | grep myproc

// 显示更多 ajx

        所以,创建进程就是创建 PCB,插入到链表中,删除进程就是移除 PCB,从链表移开( PCB 会有一个 head 作为头节点)。

进程控制块:PCB 、task_struck        

        PCB 中包含了哪些属性信息呢:

{         1:pid、ppid 唯一标识符

          2:nice 优先级

          3:mm_struct 进程空间地址,找到代码和数据的结构体指针

          4:时间片

          5:上下文信息

          6:连接信息

          。。。        }

pid:

首先是 pid :pid 是表示该进程的唯一标识符,而 ppid 是该进程的父进程的唯一标识符。

#include <unistd.h>
#include <sys/types.h>
// 获取进程ID 
getpid();
getppid();

如果要杀掉进程,可以输入:kill -9 id 终止进程,每个程序最终的父进程都是 -bash ,它是登录时创建的。

状态:

进程有多种状态:S 代表休眠 、R 代表运行等等,没有 + 号说明进程在后台。

// 让进程变成后台进程
./myproc &

问:为什么有时候有的死循环是 S+ 休眠状态?

答:OS 要刷新到显示器上,因为外设的速度太慢(显示器有行刷新),OS 的速度太快,虽然显示器在刷新,感觉在运行中,但其实大部分时间 OS 都是在休眠,以免消耗资源。

上下文指令:

        指令寄存器保存的是下一行的指令地址,每一次 CPU 执行下一行命令都会通过 eip 拿,不管是遇到循环指令或者进程临时切换, eip 都会记着下一条指令,而 CPU 做的 3 件事:取指令->分析指令->执行指令,CPU向 eip 取指令再执行,同时 eip 记录下一条指令。        

        1、每个进程都有自己的 “时间片” ,都是基于时间片轮转的。当一个进程正在执行时,时间片结束,如果某行代码数据的计算还在 CPU 中,没来得及返回,那么它会怎么办?

        当进程切换时,寄存器的数据会保存到 task_struck 中(不太准确)。

        2 、CPU 内部只有一套寄存器,内存会产生一份临时拷贝到 CPU 的寄存器中,而当前保存的中间数据,就叫做上下文数据。

        3、进程被切换,可能在任何时间点,原因是时间片到了,或者有更高优先级的进程抢占。

        4、对进程的管理就是对链表的增删查改(PCB)。

优先级:

        进程之间各有优先级,如何区分谁的更高谁的更低,进程会有一个默认 80 的 PRI:它所进程可悲执行的优先级,越小越早执行。而为了修正 PRI ,可以通过修改优先级的修正系数 nice 值, nice 值有 40 个级别,区间是 [ -20, 19 ]。

如何修改优先级:

        输入指令 top -> r -> 进程 PID -> nice 值 -> q退出,ps -la 可查看运行进程的相关信息。注意的是,每次修改都会以老的 PRI 计算,如果你是 80 ,那就每次对 80 进行修正。

环境变量:

        为什么输入命令时,可以直接执行命令,列如:执行 ls 命令,其实 ls 存在目录 /bin/ls 下,为何不用输入地址执行?就是因为 ls 是一种命令行参数。

echo $PATH :显示环境变量路径

        如果想让可执行文件直接不带 ./ 就可以执行,就 sudo cp -f exe文件 /usr/bin/ ,但是不建议这样做,因为会污染环境池,就像电脑里不注释的文件夹,久了都不清楚是什么文件,不敢删除。

所以建议用另一种方法:将自己路径导到 PATH 中,不过每次重启都会重新刷新不见。

输入命令 :

 export PATH=$PATH:/home/username/所在地址

家目录显示:

$HOME

显示当前所支持的环境变量信息:

env

显示所有变量,包括环境变量:

set  // 本地变量 VAL=100 不在环境变量中,需要 export
unset

其实,main 函数是可以带参的,完整的是:

int main(int argc, char* argv[], char* envp[])
//命令行参数个数  //命令行列表  //环境变量

        环境变量的组织方式是一个 char 类型的指针数组,以 NULL 结尾,argc、argv[] 是 C 语言设计的,是命令行参数,与系统无关,envp[] 才是系统决定的,它们都是环境变量。

        环境变量是一个系统级别的全局变量,bash 之下都可以获取,会给 main 传参( , , envp),只传环境变量,不传本地变量。

查看命令行参数以及环境变量的 3 种方法:

    // 3/
    //printf("%s\n ",getenv("MYVAL"));
    

    // 2/
    //int i = 0;
    //extern char** environ;
    //while (environ[i])
    //{
    //    printf("environ[%d] : %s\n", i, environ[i]);
    //    i++;
    //}

    // 1/
    //int i = 0;
    //while (envp[i]){
    //    printf("envp[%d] : %s\n", i, envp[i]);
    //    i++;
    //}

    // 命令行参数
    //if (argc == 2)
    //{
    //    if (strcmp(argv[1], "-a") == 0){
    //        printf("-a -a\n");
    //    }
    //    else if (strcmp(argv[1], "-b") == 0){
    //        printf("-b -b\n");
    //    }
    //    else{
    //        printf("is else\n");
    //    }
    //}
    //else{
    //    printf("no no\n");
    //}

为什么要有环境变量?为了更好的定位,在哪,是谁等等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值