【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]命令强制终止指定进程的执行。关闭该进程后,不会影响该进程的子进程或父进程,即进程(任意进程,包括父子进程)之间是有独立性的,互相是不能影响,可放心使用。


目录
打赏
0
0
0
0
1
分享
相关文章
【Linux】进程IO|系统调用|open|write|文件描述符fd|封装|理解一切皆文件
本文详细介绍了Linux中的进程IO与系统调用,包括 `open`、`write`、`read`和 `close`函数及其用法,解释了文件描述符(fd)的概念,并深入探讨了Linux中的“一切皆文件”思想。这种设计极大地简化了系统编程,使得处理不同类型的IO设备变得更加一致和简单。通过本文的学习,您应该能够更好地理解和应用Linux中的进程IO操作,提高系统编程的效率和能力。
53 34
|
8天前
|
Linux编程: 在业务线程中注册和处理Linux信号
本文详细介绍了如何在Linux中通过在业务线程中注册和处理信号。我们讨论了信号的基本概念,并通过完整的代码示例展示了在业务线程中注册和处理信号的方法。通过正确地使用信号处理机制,可以提高程序的健壮性和响应能力。希望本文能帮助您更好地理解和应用Linux信号处理,提高开发效率和代码质量。
38 17
|
8天前
|
Linux系统之whereis命令的基本使用
Linux系统之whereis命令的基本使用
50 23
Linux系统之whereis命令的基本使用
c++ linux通过实现独立进程之间的通信和传递字符串 demo
的进程间通信机制,适用于父子进程之间的数据传输。希望本文能帮助您更好地理解和应用Linux管道,提升开发效率。 在实际开发中,除了管道,还可以根据具体需求选择消息队列、共享内存、套接字等其他进程间通信方
40 16
|
17天前
|
Linux编程: 在业务线程中注册和处理Linux信号
通过本文,您可以了解如何在业务线程中注册和处理Linux信号。正确处理信号可以提高程序的健壮性和稳定性。希望这些内容能帮助您更好地理解和应用Linux信号处理机制。
50 26
Linux系统查看操作系统版本信息、CPU信息、模块信息
在Linux系统中,常用命令可帮助用户查看操作系统版本、CPU信息和模块信息
111 23
2025年1月9日更新Windows操作系统个人使用-禁用掉一下一些不必要的服务-关闭占用资源的进程-禁用服务提升系统运行速度-让电脑不再卡顿-优雅草央千澈-长期更新
2025年1月9日更新Windows操作系统个人使用-禁用掉一下一些不必要的服务-关闭占用资源的进程-禁用服务提升系统运行速度-让电脑不再卡顿-优雅草央千澈-长期更新
137 2
2025年1月9日更新Windows操作系统个人使用-禁用掉一下一些不必要的服务-关闭占用资源的进程-禁用服务提升系统运行速度-让电脑不再卡顿-优雅草央千澈-长期更新
Linux:进程间通信(共享内存详细讲解以及小项目使用和相关指令、消息队列、信号量)
通过上述讲解和代码示例,您可以理解和实现Linux系统中的进程间通信机制,包括共享内存、消息队列和信号量。这些机制在实际开发中非常重要,能够提高系统的并发处理能力和数据通信效率。希望本文能为您的学习和开发提供实用的指导和帮助。
122 20
嵌入式Linux系统编程 — 5.3 times、clock函数获取进程时间
在嵌入式Linux系统编程中,`times`和 `clock`函数是获取进程时间的两个重要工具。`times`函数提供了更详细的进程和子进程时间信息,而 `clock`函数则提供了更简单的处理器时间获取方法。根据具体需求选择合适的函数,可以更有效地进行性能分析和资源管理。通过本文的介绍,希望能帮助您更好地理解和使用这两个函数,提高嵌入式系统编程的效率和效果。
121 13
【在Linux世界中追寻伟大的One Piece】Linux进程概念
【在Linux世界中追寻伟大的One Piece】Linux进程概念
59 1
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等