【Linux系统编程】进程的认识

简介: 【Linux系统编程】进程的认识

介绍:


       进程是程序执行的实体,可将其理解为程序。比如:当我们使用文本编辑器Notepad应用程序来编写一篇文章时,此时,Notepad应用程序就被加载到了内存中,并且它占用的资源(如内存、CPU等)也得到了分配。在这个过程中,Notepad应用程序就是一个进程,此进程在使用过程将不断被执行,当关闭Notepad应用程序,此进程占用的资源将释放,进程结束。而操作系统则是负责调度和管理这个进程的实体,它为进程分配资源,并在进程结束后回收资源。也就是说,操作系统负责管理进程。


进程控制块

       进程控制块的简称为PCB,是操作系统中用于管理进程的数据结构。它包含了进程的所有状态信息,可以理解为进程属性的集合,用来描述一个进程的所有属性,是进程存在的唯一标志。


       Linux下的PCB(进程控制块)是 task_struct 结构体,此结构体是Linux内核的一种数据结构。而task_struct 结构体中的数据如下:


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


       使用ps axj指令可查看进程详细信息。其中,PID对应的就是进程的标识符,PPID对应的是父进程的标识符。标识符是用来描述本进程的唯一标示符,用来区别其他进程。

5020a08f64714351a176be00f168d5e6.png



标识符函数

       在写程序时,要想观察此进程的PID可在代码中使用 getpid() 函数,此函数可获得进程的PID,返回类型为pid_t(就是int),即谁调用getpid,就获取谁的PID。对应的还有 getppid() 函数,获取该进程的父进程标识符,返回类型为pid_t(就是int)。


       这里要说明一下,每一次启动程序时,对应的PID都会发生变化,PPID一般不会发生变化,除非您通过某种方式改变了父进程。


       在Linux中,当您启动一个程序时,该程序的PPID通常是被启动该程序的shell进程的PID,即该进程的PPID对应的就是bash或其他shell进程。可以说每启动的一个进程都是bash或shell的子进程。因此说每一次启动进程时,PID都会变化,PPID一般不会变化,除非我们将父进程也改变。


[zhu@zhujunhao day21]$ ll
total 16
-rw-rw-r-- 1 zhu zhu  305 Dec 21 17:07 code.cpp
-rwxrwxr-x 1 zhu zhu 9176 Dec 21 17:07 code.exe
[zhu@zhujunhao day21]$ cat code.cpp    //程序的源代码
#include <iostream>
#include <sys/types.h>
#include <unistd.h>
using namespace std;
int main()
{
    pid_t pid = getpid();
    pid_t ppid = getppid();
    sleep(3);
    cout << "该进程对应的PID: " << pid << endl;
    sleep(3);
    cout << "该进程对应的PPID: " << ppid << endl;
    return 0;
}
[zhu@zhujunhao day21]$ ./code.exe
该进程对应的PID: 2248
该进程对应的PPID: 1381
/*下面我们删除程序的进程,再次编译运行后可发现,该进程的PID发生了变化,PPID没有改变。该程序的PPID就是bash或shell进程*/
[zhu@zhujunhao day21]$ rm -f code.exe  
[zhu@zhujunhao day21]$ ll
total 4
-rw-rw-r-- 1 zhu zhu 305 Dec 21 17:07 code.cpp
[zhu@zhujunhao day21]$ g++ -o code.exe code.cpp  
[zhu@zhujunhao day21]$ ./code.exe   
该进程对应的PID: 2257
该进程对应的PPID: 1381

/proc目录

       下面,我们了解一下 /proc目录。/proc目录提供了一种访问系统内核内部数据结构、改变内核设置的机制。用户和应用程序可以通过访问/proc目录中的文件和子目录,来获取系统的信息,并可以改变内核的某些参数。


       其中,/proc/[pid]目录提供了访问和操作进程信息的接口,此接口提供指定进程的各种详细信息,可方便地了解和控制进程的状态和行为。


       这里要说明一下,当使用指令 ll /proc/[pid] 进行详细查看时,对应的cwd是当前进程启动的工作目录,即进程启动时所在的工作目录。exe对应的是可执行程序的工作目录,即进程运行的程序。当修改当前进程或可执行文件的工作目录时,对应的cwd或exe会发生变化。


[zhu@zhujunhao day21]$ ll /proc/1381
........
lrwxrwxrwx 1 zhu zhu 0 Dec 21 16:54 cwd -> /home/zhu/day21   //进程启动的工作目录
........
lrwxrwxrwx 1 zhu zhu 0 Dec 21 16:54 exe -> /usr/bin/bash   //可执行程序的工作目录


创建进程fork初识

       fork函数(没有参数):创建子进程,在fork之后,代码会形成分支形成两个,即代码共享,其中一个是该函数创建的一个子进程。其中,该函数返回值为pid_t,给创建的子进程返回0,父进程返回子进程的PID。


[zhujunhao@bogon code]$ cat test.cpp     //源代码
#include <iostream>
#include <sys/types.h>
#include <unistd.h>
using namespace std;
int main()
{
    cout << "PID: " << getpid() << endl;
    int ret = fork();
    cout << "ret = fork(): " << ret << endl;
    sleep(1);
    return 0;
}
[zhujunhao@bogon code]$ ./test.exe     //执行源代码的可执行程序
PID: 9655
ret = fork(): 9656  
ret = fork(): 0

       此函数通常跟 if 条件连用,分别使父子进程执行不同的功能。


[zhujunhao@bogon code]$ cat test.cpp      //源代码
#include <iostream>
#include <sys/types.h>
#include <unistd.h>
using namespace std;
int main()
{
    cout << "PID: " << getpid() << endl;
    int ret = fork();
    if (ret == 0)
    {
        cout << "I am Child: PID " << getpid() << "  PPID: " << getppid() << endl;
    }
    else 
    {
        cout << "I am father: PID " << getpid() << "  PPID: " << getppid() << endl;
    }
    sleep(1);
    return 0;
}
[zhujunhao@bogon code]$ ./test.exe   //可执行程序
PID: 10418
I am father: PID 10418  PPID: 3038
I am Child: PID 10419  PPID: 10418


       在执行进程的过程中,若不想执行该进程,通常使用 kill -9 [pid]命令强制终止指定进程的执行。关闭该进程后,不会影响该进程的子进程或父进程,即进程(任意进程,包括父子进程)之间是有独立性的,互相是不能影响,可放心使用。


相关文章
|
12天前
|
算法 Linux 调度
深入理解Linux操作系统的进程管理
本文旨在探讨Linux操作系统中的进程管理机制,包括进程的创建、执行、调度和终止等环节。通过对Linux内核中相关模块的分析,揭示其高效的进程管理策略,为开发者提供优化程序性能和资源利用率的参考。
36 1
|
1月前
|
Linux
在 Linux 系统中,“cd”命令用于切换当前工作目录
在 Linux 系统中,“cd”命令用于切换当前工作目录。本文详细介绍了“cd”命令的基本用法和常见技巧,包括使用“.”、“..”、“~”、绝对路径和相对路径,以及快速切换到上一次工作目录等。此外,还探讨了高级技巧,如使用通配符、结合其他命令、在脚本中使用,以及实际应用案例,帮助读者提高工作效率。
77 3
|
1天前
|
存储 缓存 监控
Linux缓存管理:如何安全地清理系统缓存
在Linux系统中,内存管理至关重要。本文详细介绍了如何安全地清理系统缓存,特别是通过使用`/proc/sys/vm/drop_caches`接口。内容包括清理缓存的原因、步骤、注意事项和最佳实践,帮助你在必要时优化系统性能。
97 78
|
4天前
|
Linux Shell 网络安全
Kali Linux系统Metasploit框架利用 HTA 文件进行渗透测试实验
本指南介绍如何利用 HTA 文件和 Metasploit 框架进行渗透测试。通过创建反向 shell、生成 HTA 文件、设置 HTTP 服务器和发送文件,最终实现对目标系统的控制。适用于教育目的,需合法授权。
30 9
Kali Linux系统Metasploit框架利用 HTA 文件进行渗透测试实验
|
28天前
|
缓存 Java Linux
如何解决 Linux 系统中内存使用量耗尽的问题?
如何解决 Linux 系统中内存使用量耗尽的问题?
115 48
|
7天前
|
SQL 运维 监控
南大通用GBase 8a MPP Cluster Linux端SQL进程监控工具
南大通用GBase 8a MPP Cluster Linux端SQL进程监控工具
|
15天前
|
运维 监控 Linux
Linux操作系统的守护进程与服务管理深度剖析####
本文作为一篇技术性文章,旨在深入探讨Linux操作系统中守护进程与服务管理的机制、工具及实践策略。不同于传统的摘要概述,本文将以“守护进程的生命周期”为核心线索,串联起Linux服务管理的各个方面,从守护进程的定义与特性出发,逐步深入到Systemd的工作原理、服务单元文件编写、服务状态管理以及故障排查技巧,为读者呈现一幅Linux服务管理的全景图。 ####
|
20天前
|
缓存 算法 Linux
Linux内核的心脏:深入理解进程调度器
本文探讨了Linux操作系统中至关重要的组成部分——进程调度器。通过分析其工作原理、调度算法以及在不同场景下的表现,揭示它是如何高效管理CPU资源,确保系统响应性和公平性的。本文旨在为读者提供一个清晰的视图,了解在多任务环境下,Linux是如何智能地分配处理器时间给各个进程的。
|
1天前
|
Ubuntu Linux C++
Win10系统上直接使用linux子系统教程(仅需五步!超简单,快速上手)
本文介绍了如何在Windows 10上安装并使用Linux子系统。首先,通过应用商店安装Windows Terminal和Linux系统(如Ubuntu)。接着,在控制面板中启用“适用于Linux的Windows子系统”并重启电脑。最后,在Windows Terminal中选择安装的Linux系统即可开始使用。文中还提供了注意事项和进一步配置的链接。
11 0
|
24天前
|
Ubuntu Linux 网络安全
linux系统ubuntu中在命令行中打开图形界面的文件夹
在Ubuntu系统中,通过命令行打开图形界面的文件夹是一个高效且实用的操作。无论是使用Nautilus、Dolphin还是Thunar,都可以根据具体桌面环境选择合适的文件管理器。通过上述命令和方法,可以简化日常工作,提高效率。同时,解决权限问题和图形界面问题也能确保操作的顺利进行。掌握这些技巧,可以使Linux操作更加便捷和灵活。
17 3