[Linux]---系统编程之进程概念(1)

进程概念(1)

  • 认识冯诺依曼体系
  • 简单认识操作系统
  • 进程概念
  • 进程状态
  • 进程优先级

今天,大家和我一起相约系统编程的进程概念篇,一起了解操作系统对于进程的管理,因为硬件体系结构决定了软件的行为,所以我们就不得不先了解一下冯诺依曼体系啦。

⭐冯诺依曼体系结构

我们常见的计算机,如笔记本;我们不常见的计算机,如服务器。大部分都遵守冯诺依曼体系。冯诺依曼体系结构也就是现代计算机硬件体系结构:五大硬件单元(输入设备,输出设备,运算器,控制器,存储器)。所有设备都是围绕存储器工作的。

为什么说硬件体系结构决定了软件的行为呐?例如我们写一个简单的聊天工具程序时,程序的起初应是不断等待用户的输入,数据从键盘采集,操作系统会将数据放在缓冲区中,接着程序应该控制对标准输入设备中的缓冲区数据进行处理,存放到内存中,cpu从内存中取出数据进行处理,将处理后的结果写回到内存中,然后cpu控制网卡从内存中读取数据;对端电脑通过网卡接收数据,将数据放在内存中,cpu对数据进行处理,接着放到内存,cpu控制显示器从内存中读取数据显示到屏幕上。

了解了冯诺依曼体系结构,我们会产生疑问,什么可以控制计算机的硬件呐?

⭐操作系统

  • 组成:内核+应用
  • 功能:协调管理计算机各种软硬件资源
  • 定位:搞管理的软件
  • 目的:让计算机更加好用
  • 如何管理:先描述,再组织
    在这里插入图片描述

对上幅图简单描述一下:驱动程序采集各项硬件的信息,将描述的信息交付给操作系统,操作系统将这些信息组织起来。操作系统的内核完成对各项硬件的管理,为了保护操作系统的内核部分,则向上抽象了系统调用接口(函数),让用户可以安全的使用操作系统。系统调用接口在使用上,功能比较基础,对用户的要求相对也比较高,所以,有心的开发者可以对部分系统调用进行适度封装,从而形成库,有了库,就很有利于更上层用户或者开发者进行二次开发。

😊那么问题来喽!库函数与系统调用接口的关系?
库函数封装了系统调用接口,它们是上下级关系。
在开发角度,操作系统对外会表现为一个整体,但是会暴露自己的部分接口,供上层开发使用,这部分由操作系统提供的接口,叫做系统调用。系统调用在使用上,功能比较基础,对用户的要求相对也比较高,所以,有心的开发者可以对部分系统调用进行适度封装,从而形成库,有了库,就很有利于更上层用户或者开发者进行二次开发。

我们已经初步的了解了操作系统对于硬件的管理方式是先描述,在组织。那么我们接着应该探索,操作系统对于软件资源(进程)是如何进行管理的?

⭐进程的概念

😊什么是进程?
进程就是运行中的程序,站在操作系统角度来说,进程就是一个运行中程序的描述-PCB,在linux下,这个pcb是一个结构体 struct task_struct{…},操作系统通过这个pcb的描述来完成对程序运行的调度。所以说,进程就是PCB。
在这里插入图片描述
如何描述一个运行中的程序:

  • 内存指针:指向程序被加载到内存中的位置
  • 程序计数器:程序下一步即将执行的指令
  • 上下文数据:上一次正在处理的数据
  • 优先级:让操作系统运行的更加良好
  • I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
  • 记账信息:进程在cpu上运行的时间
  • 还有标识符PID以及进程状态

接下来,我们探索探索进程的状态有哪些!

⭐进程状态

在linux系统中,进程共有7种状态:运行状态-R ,可中断休眠状态-S ,不可中断休眠状态-D ,停止状态-T ,死亡状态-X ,追踪状态-t ,僵死状态-Z。

对于僵死状态我们着重了解一下,如果对于其他的进程状态也感兴趣的小伙伴们可以上网查找查找资料哦!

  • 僵死状态:进程已经退出,但是资源没有完全释放
  • 僵尸进程:处于僵死状态的进程
  • 僵尸进程的危害:资源泄露
  • 僵尸进程的避免:进程等待
  • 僵尸进程的处理:退出父进程 (kill PPID)
  • 僵尸进程的产生:子进程先于父进程退出,为了保存退出原因,资源并没有完全被释放,因此在子进程退出时,操作系统通知父进程,让父进程获取子进程推出的原因,然后释放子进程的所有资源。如果父进程当前并没有关注子进程的退出状态,则子进程成为僵尸进程。

所以,我们在代码中创建了子进程,如果子进程先于父进程退出,那么子进程会成为僵尸进程。那么假如父进程先于子进程退出呐?----则子进程会成为孤儿进程!

孤儿进程:父进程先于子进程退出,子进程成为孤儿进程,运行在后台,父进程成为1号进程(init进程),孤儿进程退出不会成为僵尸进程,因为1号进程会处理它。

了解了孤儿进程,我们就不得不说一下特殊的孤儿进程啦----精灵进程,也叫守护进程。精灵进程是在孤儿进程的基础上,脱离终端脱离登录会话。通常运行在后台,默默的工作,处理批处理文件,不希望受到终端会话的影响。

上面我们了解了3种不同的进程,这时候会有一些聪明的小伙伴们产生了疑问!我们在程序中如何创建一个子进程呐!

进程的创建:pid_t fork ( void )
解释这个函数:通过复制调用进程创建一个子进程,子进程因为拷贝了父进程PCB里边的很多数据,因此与父进程的内存指针以及程序计数器都相同,所以运行的代码以及运行的位置都一样。
返回值有三种:
-1:创建子进程失败
等于0:对于子进程,返回值是0
大于0:对于父进程,返回值是父进程的pid功能:根据返回值的不同,可以实现代码分流,让父子进程执行不同的程序。
但是子进程也不是将父进程所有的信息都复制,fork创建子进程后,父子进程代码共享,数据独有。

下面来一个代码,让我们体会体会什么叫资源共享,数据独有!

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int gval=100;
int main()
{
    int ppid=getpid(); //得到父进程的pid
    int pid=fork();    //fork创建子进程后,父子进程代码共享,数据独有
    if(pid>0)          
    {
        gval=10;//parent
    }
    else if(pid==0)
    {
        sleep(3);//child,让子进程先睡3秒钟,先执行父进程还是子进程不确定,所以为了先执行父进程,则让子进程先睡3秒钟
    }
    printf("加油--%d,pid=%d---ppid=%d\n",gval,getpid(),ppid);
    //getpid(),ppid一样,则为父进程;不一样,则为子进程
    return 0;
 }

在Linux下如何查看进程的信息?
ps -ef:查看所有的进程信息
包含的信息有:UID:属于哪个用户 ,PID:进程ID,PPID:父进程, STIME:运行起始时间,TTY:终端(?表示未知终端),TIME:在 CPU上运行的时间,CMD:程序名称。
ps -aux:比-ef查看的信息更加详细
例如可以看到:%CPU:cpu的使用率 ,%MEM:内存的使用率,VSZ:虚拟内存大小,RSS:物理内存大小,STAT:状态。

进程分为批处理进程和交互式进程,交互式进程强调用户和电脑的交互,为了用户的体验良好,则它的进程优先级较高。那么我们能不能修改进程的优先级呐?

⭐进程优先级

进程优先级的作用:决定进程cpu资源的优先分配权,为了让操作系统分配的更加合理。
在linux中,进程的优先级用数字表示,使用ps -efl命令可以查看进程的优先级,数字越大,优先级越低;数字越小,优先级越高。
优先级可以通过NI值修改,NI(nice值)是有范围的,从-19~20;也可以在程序运行的时候修改优先级。
两种方式对应的命令:
(1) renice -n NI值 -p PID
(2) nice -n NI值 ./程序名
需要注意一点:调高进程的优先级需要管理员权限,降低进程优先级不需要管理员权限。

😊OK,今天笔者先总结到这里。如有问题或者疑惑,欢迎各位小伙伴们指出。我们一起交流,一起进步!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值