[Linux]进程概念

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

[Linux]进程概念

进程的定义

进程是程序的一个执行实例,是担当分配系统资源(CPU时间,内存)的实体。

进程和程序的关系

由编程语言编写的代码经过编译后形成的二进制程序会存储在硬盘中,当计算机启动一个程序时,会将程序的相关代码和和数据加载到内存中,供CPU来使用:

[Linux]进程概念,Linux,linux,运维,服务器,centos

程序的代码和数据加载到内存后,操作系统就要对程序进行管理,为了更好的管理这些程序,需要对先创建相应的结构来描述这些程序,在操作系统中,用于描述程序的结构叫做进程控制块(Process Control Block,简称 PCB),Linux系统下的PCB名为task_struct,PCB中也会记录相应的代码和数据的地址,为了更好的访问这些PCB使用链式结构将其组织起来:

[Linux]进程概念,Linux,linux,运维,服务器,centos

task_ struct内容分类如下:

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

如果只是将程序的代码和数据加载到内存中,但是操作系统没有为其创建PCB进行管理,操作系统就不会调度它,它就无法完成程序的执行,因此进程的本质是内存中的代码和数据+进程控制块,有了PCB后,操作系统就将对进程的管理转化为了对PCB的管理,比如如果要关闭一个进程就将其PCB删除,然后对应的内存就会清空其在内存中的代码和数据:

[Linux]进程概念,Linux,linux,运维,服务器,centos

Linux下查看进程

为了更好的在Linux操作系统上查看进程,创建源文件myprocess.c和makefile文件来创建二进制程序,

源文件中内容如下:

#include <stdio.h>
#include <unistd.h>

int main()
{
  while(1)
  {
    printf("hello myprocess\n");
    sleep(1);
  }
  return 0;
}

其中makefile的内容如下:

myprocess:myprocess.c
	gcc -o myprocess myprocess.c
.PHONY:clean
clean:
	rm -f myprocess

创建好以上文件并编译得到名为myprocess的二进制程序,然后在Linux下启动两个客户端,其中一个启动程序变成进程:

[Linux]进程概念,Linux,linux,运维,服务器,centos

再另一个客户端输入ps axj | head -1 && ps axj | grep myprocess | grep -v grep查看myprocess进程:

[Linux]进程概念,Linux,linux,运维,服务器,centos

以上为使用指令查看进程,指令如下:

ps axj | head -1 && ps axj | grep 进程名 | grep -v 进程名

另外还可以在/proc目录下看到进程:

[Linux]进程概念,Linux,linux,运维,服务器,centos

/proc目录是一个内存级的目录,不存在于硬盘中,目录中会有命名和pid相同的目录,该目录中会记录对应进程的task_struct,如果进程关闭了对应的目录也就删除了。

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

Linux操作系统为了唯一标识一个进程,给每个进程设置了一个进程标识符在PCB中,也就是pid。并且也提供了系统接口函数getpid来获取当前进程的pid,其介绍如下:

[Linux]进程概念,Linux,linux,运维,服务器,centos

为了测试getpid函数修改源文件myprocess.c,内容如下:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
  while(1)
  {
    printf("hello myprocess, 我的pid是%d\n", getpid());
    sleep(1);
  }
  return 0;
}

用指令查询进程pid和查看进程执行结果:

[Linux]进程概念,Linux,linux,运维,服务器,centos

另外Linux操作系统中还设置了父进程标识符,用于记录当前进程的父进程pid,也就是ppid,同时也提供了getppid函数来获取当前进程的ppid,ppid的介绍如下:

[Linux]进程概念,Linux,linux,运维,服务器,centos

为了测试getppid函数修改源文件myprocess.c,内容如下:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
  while(1)
  {
    printf("hello myprocess, 我的pid是%d, 我的ppid为%d\n", getpid(), getppid());
    sleep(1);
  }
  return 0;
}

用指令查询进程pid和查看进程执行结果:

[Linux]进程概念,Linux,linux,运维,服务器,centos

多次利用 ctrl+c关闭进程,然后重新启动进程:

[Linux]进程概念,Linux,linux,运维,服务器,centos

可以看出,无论进程的pid如何变化,进程的ppid都不会变化,我们尝试用指令查看这个父进程:

[Linux]进程概念,Linux,linux,运维,服务器,centos

实际上这个这个父进程就是bash,通过如上现象我们可以得到如下结论:

  • 命令行解释器(bash)本质也是一个进程。
  • 命令行启动的所有程序最终都会变成进程,而该进程对应的父进程都是bash。

Linux下通过系统调用创建进程-fork函数使用

fork函数是Linux系统提供的创建子进程的系统调用。

  • fork函数运行成功后,执行流会变成两个,一个是调用fork函数的父进程,另一个是fork函数创建的子进程。
  • 创建的子进程会和父进程共享父进程代码和数据,子进程会执行父进程fork函数创建子进程之后的代码。
  • fork函数给父进程返回子进程的pid,给创建的子进程返回0,出错返回-1。

为了测试fork函数修改源文件myprocess.c,内容如下:

#include <stdio.h>
#include <assert.h>
#include <unistd.h>

int main()
{
  pid_t id = fork();
  if (id == 0)
  {
    //子进程
    printf("我是子进程,我的pid是%d, 我的ppid是%d\n", getpid(), getppid());
    sleep(2);
  }
  else if (id > 0)
  {
    //父进程
    printf("我是父进程,我的pid是%d, 我的ppid是%d\n", getpid(), getppid());
    sleep(3);
  }
  else 
  {
    //fork函数出错
    assert(1);
  }
  return 0;
}

说明:

  • fork函数所需要的头文件是unistd.h
  • 使用条件判断来控制父子进程执行不同的代码。

用指令查询进程和查看进程执行结果:

[Linux]进程概念,Linux,linux,运维,服务器,centos

fork函数的原理

进程的本质是PCB+内存中的代码和数据,由于fork函数创建的子进程是和父进程共享代码和数据的,因此fork函数创建子进程的原理是创建一个PCB给子进程,该PCB中大部分数据是和父进程相同的,并且指向同一份代码和数据:

[Linux]进程概念,Linux,linux,运维,服务器,centos

进程独立性在fork中的体现

首先给出如下定理:进程之间是相互独立的,一个进程的任何操作都不会影响其他进程。

在使用fork函数创建子进程进程之间的独立性也能得到保证,为了验证独立性修改源文件myprocess.c,内容如下:

#include <stdio.h>
#include <assert.h>
#include <unistd.h>

int main()
{
  pid_t id = fork();
  if (id == 0)
  {
    //子进程
    printf("我是子进程,我的pid是%d, 我的ppid是%d\n", getpid(), getppid());
    sleep(20);
    printf("我是子进程,我的pid是%d, 我的ppid是%d\n", getpid(), getppid());
    printf("我是子进程,我已经关闭了\n");
  }
  else if (id > 0)
  {
    //父进程
    printf("我是父进程,我的pid是%d, 我的ppid是%d\n", getpid(), getppid());
    sleep(3);
    printf("我是父进程,我已经关闭了\n");
  }
  else 
  {
    //fork函数出错
    assert(1);
  }
  return 0;
}

用指令查询进程和查看进程执行结果:

开始时,父子进程一起执行:

[Linux]进程概念,Linux,linux,运维,服务器,centos

父进程关闭,子进程正常运行:

[Linux]进程概念,Linux,linux,运维,服务器,centos

最后子进程关闭:

[Linux]进程概念,Linux,linux,运维,服务器,centos

由以上测试可以看出,父进程的关闭不影响子进程正常执行,保证了一定的独立性。另外由于代码是只读的,父进程无法通过修改代码来影响子进程,而数据的修改会触发写时拷贝机制,保证了一定的独立性。

为了观察写时拷贝现象,修改源文件myprocess.c,内容如下:

#include <stdio.h>
#include <assert.h>
#include <unistd.h>

int main()
{
  int a = 0;
  pid_t id = fork();
  if (id == 0)
  {
    //子进程
    printf("我是子进程,我的pid是%d, 我的ppid是%d, a:%d, &a:%p\n", getpid(), getppid(), a, &a);
    sleep(5);
    printf("我是子进程,我的pid是%d, 我的ppid是%d, a:%d, &a:%p\n", getpid(), getppid(), a, &a);
  }
  else if (id > 0)
  {
    //父进程
    printf("我是父进程,我的pid是%d, 我的ppid是%d, a:%d, &a:%p\n", getpid(), getppid(), a, &a);
    a = 666;
    printf("我是父进程,我的pid是%d, 我的ppid是%d, a:%d, &a:%p\n", getpid(), getppid(), a, &a);
    sleep(3);
    printf("我是父进程,我已经关闭\n");
  }
  else 
  {
    //fork函数出错
    assert(1);
  }
  return 0;
}

查看进程执行结果:

[Linux]进程概念,Linux,linux,运维,服务器,centos

观察现象可以发现,父进程修改a的值后,子进程的a的值并没有改变,但是父进程和子进程的a变量的地址是相同,这就是发生了写时拷贝造成的现象。

fork函数返回两个返回值的原理

由于fork创建的子进程和父进程共享代码和数据,并且fork函数也是父进程的代码的一部分,因此父进程完成子进程的创建后,子进程也会执行fork函数创建子进程后续的剩余代码,其中就包括fork函数中return返回的部分,因此父进程执行了return部分,子进程也执行了return部分,造成fork函数返回两个返回值的现象:

[Linux]进程概念,Linux,linux,运维,服务器,centos文章来源地址https://www.toymoban.com/news/detail-667366.html

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

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

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

相关文章

  • Linux服务器上查询进程 ps aux

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

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

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

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

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

    2024年02月02日
    浏览(42)
  • 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日
    浏览(56)
  • 【服务端】CentOS Linux 7 搭建邮件服务器

    参考:CentOS7搭建简单的邮件服务器 - 秋夜雨巷 - 博客园 (cnblogs.com) 在 CentOS7 中搭建邮件服务器,给QQ邮箱发邮件。简单记录一次搭建过程。 目录 前言 一、基础环境准备 二、配置域名解析 1. 登录阿里云 三、安装邮件服务 1. 登录主机,配置yum源(配置阿里云yum源步骤略) 2

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

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

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

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

    2024年02月04日
    浏览(83)
  • Linux centos搭建web服务器

    在web项目中,部署的web站点需要被外部访问,则需要一个媒介,通过把资源放在这个媒介中,再通过所暴露的端口指向这个站点,当外部访问这个媒介所对应的端口时,媒介指向站点,完成访问,像这种类似的媒介,常用的有tomcat容器、Apache等,这边使用Apache来建搭建。 Apache2 是一种流行的

    2023年04月19日
    浏览(60)
  • Linux CentOS 服务器清理磁盘空间

    首先根目录下使用[df -ah]命令查询磁盘空间占用情况。 发现[/根目录]下面磁盘占用100% 进入根目录,查询大文件与目录 查看GB以上文件夹目录并且排序,可以使用以下命令: 然后不断执行上面的过程,进入大文件目录,定位到大文件 我这里最终找到是Tomcat下面logs日志占据了20多

    2024年02月05日
    浏览(71)
  • 蓝易云:Linux系统sshd命令 – openssh服务器守护进程

    sshd是Linux系统中的一个守护进程,它提供了远程登录服务和安全的文件传输功能。以下是sshd的详细教程。 1. 安装openssh-server 在Debian/Ubuntu上安装openssh-server命令如下: sudo apt-get update sudo apt-get install openssh-server 在CentOS/RHEL上安装openssh-server命令如下: sudo yum update sudo yum install

    2024年02月16日
    浏览(49)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包