【Linux系统】进程概念

这篇具有很好参考价值的文章主要介绍了【Linux系统】进程概念。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1 冯诺依曼体系结构

2 操作系统(Operator System)

概念

设计OS的目的

定位

总结

系统调用和库函数概念

3 进程

3.1 基本概念

3.2 描述进程-PCB

3.2 组织进程

 3.3 查看进程

3.4  通过系统调用获取进程标示符

3.5 进程状态


在了解进程概念前我们还得了解下冯诺依曼体系结构和操作系统的概念与定位。

1 冯诺依曼体系结构

我们常见的计算机,如笔记本。我们不常见的计算机,如服务器,大部分都遵守冯诺依曼体系:
【Linux系统】进程概念,Linux,linux,服务器,运维
  • 输入单元:包括网卡,键盘鼠标,扫描仪, 写板,话筒等 ;
  • 中央处理器(CPU):含有运算器和控制器等 ;
  • 输出单元:网卡,显示器,打印机等;

 关于冯诺依曼,必须强调几点:

  • 这里的存储器指的是内存 ;
  • 不考虑缓存情况,这里的CPU能且只能对内存进行读写,不能访问外设(输入或输出设备) ;
  • 外设(输入或输出设备)要输入或者输出数据,也只能写入内存或者从内存中读取;
  • 一句话,所有设备都只能直接和内存打交道;
对冯诺依曼的理解,不能只停留在概念上,要深入到对软件数据流理解上,请解释,从你登录上qq开始和某位朋友聊天开始,数据的流动过程。
在不考虑网络层情况下,小明用qq向小红发送了一条消息,小明的电脑从键盘上读取信息然后加载到内存,再从内存将数据通过一系列操作发送到输出设备上(网卡),然后通过一系列的网络操作将数据发送到小红的输入设备上(网卡),小红的电脑再从输入设备中将数据读到内存,然后通过输出设备(显示器)将信息刷新到小红的电脑上,这里数据刷新是两个方面的,再成功发送后小明的电脑也会显示出已经成功发送后的信息。

2 操作系统(Operator System)

概念

任何计算机系统都包含一个基本的程序集合,称为操作系统(OS)。笼统的理解,操作系统包括:

  • 内核(进程管理,内存管理,文件管理,驱动管理)
  • 其他程序(例如函数库,shell程序等等)

 设计OS的目的

  • 与硬件交互,管理所有的软硬件资源
  • 为用户程序(应用程序)提供一个良好的执行环境

 定位

在整个计算机软硬件架构中,操作系统的定位是:一款纯正的搞管理的软件。

总结

计算机管理硬件
  1. 描述起来,用struct结构体
  2. 组织起来,用链表或其他高效的数据结构

 系统调用和库函数概念

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

3 进程

有了上面对冯诺依曼体系结构和操作系统的理解,我们自然可以想到进程也是先描述,再组织。

3.1 基本概念

  • 课本概念:程序的一个执行实例,正在执行的程序等
  • 内核观点:担当分配系统资源(CPU时间,内存)的实体。

 有些教材书上甚至是给出这样的定义的:进程就是程序加载到内存中。但是我觉得这种描述是狭隘的不够具体的,具体的我们下面会给出解释.

3.2 描述进程-PCB

  • 进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合。
  • 课本上称之为PCBprocess control block),Linux操作系统下的PCB: task_struct
task_struct是PCB 的一种:
  • Linux中描述进程的结构体叫做task_struct
  • task_structLinux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息

 我们将所有进程的属性用一个队列来维护,当我们想要加载程序时就将它的PCB链接到该运行队列中,这样就很好的维护了进程。

【Linux系统】进程概念,Linux,linux,服务器,运维

 那现在我们再来回答什么是进程?

进程=当前程序的代码和数据+内核关于进程的相关数据结构

task_ struct内容分类:

  • 标示符: 描述本进程的唯一标示符,用来区别其他进程。
  • 状态: 任务状态,退出代码,退出信号等。
  • 优先级: 相对于其他进程的优先级。
  • 程序计数器: 程序中即将被执行的下一条指令的地址。
  • 内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
  • 上下文数据: 进程执行时处理器的寄存器中的数据[休学例子,要加图CPU,寄存器]
  • IO状态信息: 包括显示的I/O请求,分配给进程的IO设备和被进程使用的文件列表。
  • 记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
  • 其他信息

3.2 组织进程

  • 可以在内核源代码里找到它。所有运行在系统里的进程都以task_struct链表的形式存在内核里。

 3.3 查看进程

我们在Linux环境中创建了一个profile.cpp的Cpp文件,然后编译运行生成了一个叫做profile的可执行文件,我们可以通过一下命令来查找进程:

ps ajx | head -1 && ps ajx | grep "查找进程的名字"

当我们运行profile后来查看:

【Linux系统】进程概念,Linux,linux,服务器,运维

 不难发现我们查询到了profile进程的一些基本信息,如果我们想不加上下面那一行的信息可以将命令后面多加一些内容:

ps ajx | head -1 && ps ajx | grep "查找进程的名字" | grep -v grep

【Linux系统】进程概念,Linux,linux,服务器,运维

 当然,文件名可加可不接双引号。

我们还可以在./proc中查询:

ls ./proc

【Linux系统】进程概念,Linux,linux,服务器,运维

3.4  通过系统调用获取进程标示符

  • 进程idPID
  • 父进程idPPID

 我们向profile.cpp中写入以下代码:

  1 #include<iostream>
  2 #include<sys/types.h>
  3 #include<unistd.h>
  4 using namespace std;
  5 
  6 
  7 int main()
  8 {
  9   while(1)
 10   {
 11     pid_t ret=getpid();
 12     cout<<"hello"<<ret<<" "<<endl;
 13     pid_t t=fork();
 14     if(t==0)
 15     {
 16       while(1)
 17       {
 18       cout<<"我是一个子进程"<<" pid:"<<getpid()<<" ppid:"<<getppid()<<endl;
 19       sleep(1);
 20       }
 21     }
 22     else if(t>0)
 23     {                                                                                                                                                      
 24       while(1)
 25       {
 26       cout<<"我是一个父进程"<<" pid:"<<getpid()<<" ppid:"<<getppid()<<endl;
 27       sleep(1);
 28       }
 29     }
 30   }
 31   return 0;
 32 }

当我们查看进程时:

【Linux系统】进程概念,Linux,linux,服务器,运维

 fork()后执行流会变成两个,是先执行父进程还是子进程是由调度器决定的,fork()后的代码共享,我们通常是用if else 来进行分流的。

  • 运行 man fork 认识fork
  • RETURN VALUE
           On success, the PID of the child process is returned in the parent, and  0
           is  returned  in  the child.  On failure, -1 is returned in the parent, no
           child process is created, and errno is set appropriately.
  • fork有两个返回值
  • 父子进程代码共享,数据各自开辟空间,私有一份(采用写时拷贝)

 当我们只读数据不写数据时,父子进程是共享代码的,而当有其中一个执行流尝试修改数据时OS就会在当前进程触发写时拷贝另外生成一份。

如何理解有两个返回值呢?

创建子进程本质上就是OS提供的一个函数,当函数内部进行return 时我们主体功能已经完成了。

3.5 进程状态

在了解进程状态前我们还得了解下什么是阻塞和挂起?

相信大家在看一些操作系统的书的时候就见过类似于这样的图片:

【Linux系统】进程概念,Linux,linux,服务器,运维

 阻塞状态是一种等待某种资源就绪,而导致的一种不被推进的过程。这么说有点儿抽象,我们来举一个栗子:

当有大量进程存在时我们是不是要先描述,再组织,前面我们说过组织进程靠的是内核中以某种数据结构来维护进程的PCB。假设你在应用市场要下载一个软件,但是下到一半时网络突然中断了,那么操作系统会一直等到网络资源恢复后再去运行其他进程吗?显然是不会的,假如操作系统这样设计的话那么难道我们电脑上的其他程序就不运行了吗?就只等你一个?所以当网络资源中断时操作系统会将该进程从CPU的运行队列中拿走,放到对应硬件资源的等待队列中,等到网络资源恢复后再将该进程链接到CPU的运行队列中执行,而这种等待某种资源就绪而不被推进的一种状态就叫做阻塞状态。

【Linux系统】进程概念,Linux,linux,服务器,运维

 而挂起又是什么意思呢?

由于机器的资源是有限的,在资源不足的情况下操作系统可以暂时将一些在内存中的进程淘汰出局,当条件允许的时候又会被操作系统给调回来,这个比较好理解就不在多做解释了。

看看Linux内核源代码怎么说

下面的状态在kernel源代码里定义:

/*
* The task state array is a strange "bitmap" of
* reasons to sleep. Thus "running" is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};
  • R运行状态(running: 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。
  • S睡眠状态(sleeping): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠 interruptible sleep))。
  • D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。
  • T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可 以通过发送 SIGCONT 信号让进程继续运行。
  • X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态。

第一个R状态并不是表示进程在运行中,有可能是在运行队列里面。接下来给出大家一个程序大家猜猜这时一种什么状态?

  1#include<iostream>
  2 #include<unistd.h>
  3 using namespace std;
  4 
  5 int main()
  6 {
  7   while(1)
  8   {
  9     cout<<"我是一个进程 我的pid是:"<<getpid()<<endl;           
 10   }
 11   return 0;
 12 }

我相信第一次大家或许都会想:既然是死循环那么程序肯定在运行状态了,也就是R状态,事实真的是这样吗?我们一起来看看:

【Linux系统】进程概念,Linux,linux,服务器,运维

 我们居然惊奇的发现,该进程居然处于S状态,这不合理吧?

其实大家想想,我们使用cout往显示屏中打印字符串,这里的输出设备就是我们的屏幕,但是输入输出设备是很慢的相对于CPU来说,可能当输入输出一个字符时CPU就已经跑了上百万行代码了。所以当我们往显示屏打印字符串时,操作系统并不会直接将该进程直接运行,而是等到当某种资源就绪后会将该进程链接到运行队列中,那这S状态与我们上面讲的阻塞状态有点儿类似呀,其实S状态本质就是阻塞状态。(要想获得R状态就得在资源准备就绪的一瞬间来用命令查看,太难抓了,我就不演示了)

那后面的+号是什么意思呢?

这里+表示该进程是前台运行的,当我们使用ctrl+c的时候能够终止掉该进程,不写+表示的是后台运行的,这时用ctrl+c是无法终止掉该程序的,要用命令杀掉进程来终止,我们接下来会介绍的。

 当我们注释掉代码里的打印字符时:

  1 #include<iostream>
  2 #include<unistd.h>
  3 using namespace std;
  4 
  5 int main()
  6 {
  7   while(1)
  8   {
  9    // cout<<"我是一个进程 我的pid是:"<<getpid()<<endl;               
 10   }                     
 11   return 0;             
 12 }               

再来看看:

【Linux系统】进程概念,Linux,linux,服务器,运维

 我们会发现代码进程的状态已经变成了R.

同理,当我们往键盘中输入数据时几乎绝大多数都是S状态,只有刚输入数据那一瞬间才是R状态。

D状态是一种不可中断休眠状态,这时就算是强如操作系统都不能够干掉他,但是这种场景一般很少见,除非机器快宕机了。

T状态是一种停止状态,我们可以通过一个命令来改变当前的状态位T状态,大家可以查看有哪些kill命令:

kill -l

这时就会出现很多与kill相匹配的选项:

1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP
 6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM
16) SIGSTKFLT	17) SIGCHLD	18) SIGCONT	19) SIGSTOP	20) SIGTSTP
21) SIGTTIN	22) SIGTTOU	23) SIGURG	24) SIGXCPU	25) SIGXFSZ
26) SIGVTALRM	27) SIGPROF	28) SIGWINCH	29) SIGIO	30) SIGPWR
31) SIGSYS	34) SIGRTMIN	35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3
38) SIGRTMIN+4	39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12	47) SIGRTMIN+13
48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14	51) SIGRTMAX-13	52) SIGRTMAX-12
53) SIGRTMAX-11	54) SIGRTMAX-10	55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7
58) SIGRTMAX-6	59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2
63) SIGRTMAX-1	64) SIGRTMAX

这里我们使用19号命令来暂停进程:

kill -19 进程的pid

【Linux系统】进程概念,Linux,linux,服务器,运维

 那如何恢复呢?

可以用kill命令配带的18号选项:

kill -18 进程的pid

 【Linux系统】进程概念,Linux,linux,服务器,运维

 但是大家发现没有,这里的S状态是没有加+,也就是该进程是在后台运行的,不可以被ctrl+c终止

【Linux系统】进程概念,Linux,linux,服务器,运维

 这时应该怎么处理呢?

我们可以试试kill带的9号选项:

kill -9 进程的pid

【Linux系统】进程概念,Linux,linux,服务器,运维

 这时该进程已经被干掉了。

除了T状态还有一个t状态,这里的t表示的一种追踪暂停,类似于我们打断点运行到断点处:

我们可以打开Makefile加入断点信息,然后调试起来

【Linux系统】进程概念,Linux,linux,服务器,运维

 不难发现此时的状态已经变成了t.

至于后面的X和Z状态将会放在下一节课来讲解,如果该文对你有帮助的话能不能3连支持一下博主呢?文章来源地址https://www.toymoban.com/news/detail-787965.html

到了这里,关于【Linux系统】进程概念的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • linux并发服务器 —— 多进程并发(四)

    程序是包含一系列信息的文件,描述了如何在运行时创建一个进程; 进程是正在运行的程序的实例,可以用一个程序来创建多个进程; 用户内存空间包含程序代码以及代码所使用的变量,内核数据结构用于维护进程状态信息; 进程控制块(PCB):维护进程相关的信息,tas

    2024年02月11日
    浏览(51)
  • 【Linux 服务器运维】定时任务 crontab 详解 | 文末送书

    本文思维导图概述的主要内容: 1.1 什么是 crontab Crontab 是一个在 Unix 和 Linux 操作系统上 用于定时执行任务 的工具。它允许用户创建和管理计划任务,以便在特定的时间间隔或时间点自动运行命令或脚本。Crontab 是 cron table 的缩写, cron 指的是 Unix 系统中的一个后台进程,它

    2024年02月08日
    浏览(85)
  • Linux服务器上查询进程 ps aux

    在Linux服务器上查询进程,有以下几种方法: 使用ps命令。这个命令用于报告当前系统的进程状态。可以用以下方式使用ps命令来查看进程信息: ps aux:显示系统中所有进程的信息。 ps -e:显示所有进程的信息。 ps -f:显示进程的所有信息。 ps -l:以长格式显示进程信息。

    2024年02月05日
    浏览(59)
  • 【Linux运维】shell脚本检查服务器内存和CPU利用率

    在管理服务器时候写了一个 shell脚本,在服务上实现每天凌晨3点查系统的指定文件夹下的容量大小,如果超过10G就要删除3天前的内容,还要时刻查询内存和cpu利用率,如果超过80%就要提示用户出现过载 将以上代码保存为一个.sh文件,然后通过crontab在每天凌晨3点运行即可:

    2024年02月09日
    浏览(65)
  • Linux服务器中查看进程的四种方法

    1. 使用 ps aux 命令来查看,能以简单列表的形式显示出进程信息 ps aux 用于报告当前系统的进程状态。可以搭配kill指令随时中断、删除不必要的程序. ps 命令是最基本同时也是非常强大的进程查看命令,使用该命令可以确定有哪些进程正在运行和运行的状态、进程是否结束、进

    2024年02月02日
    浏览(40)
  • Linux网络编程:多进程 多线程_并发服务器

    文章目录: 一:wrap常用函数封装 wrap.h  wrap.c server.c封装实现 client.c封装实现 二:多进程process并发服务器 server.c服务器 实现思路 代码逻辑  client.c客户端 三:多线程thread并发服务器 server.c服务器 实现思路 代码逻辑  client.c客户端 ​​​​   read 函数的返回值 wrap.h  wrap

    2024年02月12日
    浏览(54)
  • Linux服务器常见运维性能测试(1)综合跑分unixbench、superbench

    最近需要测试一批服务器的相关硬件性能,以及在常规环境下的硬件运行稳定情况,需要持续拷机测试稳定性。所以找了一些测试用例。本次测试包括在服务器的高低温下性能记录及压力测试,高低电压下性能记录及压力测试,常规环境下CPU满载稳定运行的功率记录。 这个系

    2024年02月04日
    浏览(75)
  • Linux本地部署1Panel服务器运维管理面板并实现公网访问

    1Panel 是一个现代化、开源的 Linux 服务器运维管理面板。高效管理,通过 Web 端轻松管理 Linux 服务器,包括主机监控、文件管理、数据库管理、容器管理等 下面我们介绍在Linux 本地安装1Panel 并结合cpolar 内网穿透工具实现远程访问1Panel 管理界面 执行如下命令一键安装 1Panel: 安

    2024年02月04日
    浏览(92)
  • 基于linux下的高并发服务器开发(第二章)- 2.7 进程退出、孤儿进程、僵尸进程

    ◼ 父进程运行结束,但子进程还在运行(未运行结束),这样的子进程就称为孤儿进程 (Orphan Process)。 ◼ 每当出现一个孤儿进程的时候,内核就把孤儿进程的父进程设置为 init ,而 init 进程会循环地 wait() 它的已经退出的子进程。这样,当一个孤儿进程凄凉地结束 了其生

    2024年02月16日
    浏览(52)
  • [1Panel]开源,现代化,新一代的 Linux 服务器运维管理面板

    本期测评试用一下1Panel这款面板。1Panel是国内飞致云旗下开源产品。整个界面简洁清爽,后端使用GO开发,前端使用VUE的Element-Plus作为UI框架,整个面板的管理都是基于docker的,想法很先进。官方还提供了视频的使用教程,本期为大家按照本专栏的基本内容进行多方面的测评。

    2024年02月07日
    浏览(89)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包