初识 Linux 进程

news/2024/11/24 13:27:17/

问题

strace 输出中的 execve(...) 究竟是什么?

进程生命周期

操作系统内部定义了进程的不同状态

Linux 进程基本概念

进程是 Linux 任务的执行单元,也是 Linux 系统资源的分配单元

每个 Linux 应用程序运行后由一个或多个进程构成

每个 Linux 进程可以执行一个或多个程序

Linux 进程有多种不同状态 (即:Linux 进程有不同的活法)

Linux 进程生命周期

可中断状态表示进程可以接收到内核给它发出的信号,不可中断状态表示进程不接收内核给它发出的信号

僵尸状态表示进程的生命周期已经结束了,但内核还残留着这个进程的资源

我们查看下当前的命令行所运行的进程

ps ax 命令查看每个运行进程的信息,grep "pts/2" 用来筛选当前命令行所运行的进程

第一列是每个进程的进程号,第三列是每个进程的状态

下图包含了进程的状态信息

S 表示该进程处于可中断的阻塞状态,R 表示该进程处于运行或就绪状态

s 表示该进程是会话组长,+ 表示该进程在前台进程组里

Linux 进程必知必会

每一个进程都有一个唯一的标识 (PID)

每个进程都是由另一个进程创建而来 (即:父进程)

getpid() 用于获取当前进程的进程号,getppid() 用于获取当前进程的父进程号

Linux 进程树

整个 Linux 系统的所有进程构成一个树状结构

树根由内核自动创建即:IDLE (PID = 0)

系统中的第一个进程是 init / systemd (PID = 1)

0 号进程创建 1 号进程,1 号进程负责完成内核部分初始化工作

1 号进程加载执行初始化程序,演变为用户态 1 号进程

我们来查看下当前命令行进程的进程树

pstree 是查看当前系统进程树的命令,-p 参数会展示出每个进程的 pid,-s 参数表示指定查看某个进程,$$ 代表当前进程的 pid 

Linux 进程创建

pid_t fork(void); 

  • 通过当前进程创建新进程,当前进程为父进程,新进程为子进程

int execve(const char* pathname, char* const argv[], char* const envp[]);

  • 在当前进程中执行 pathname 指定的程序代码

fork() 的工作方式

为子进程申请内存空间,并将父进程数据完全复制到子进程空间中

两个进程中的程序执行顺序完全一致 (fork() 函数调用位置)

不同之处:

  • 父进程:fork() 返回子进程 pid
  • 子进程:fork() 返回0
  • 通过 fork() 返回值判断父子进程,执行不同代码

fork() 初探

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>static int g_global = 0;int main()
{int pid = 0;printf("Hello World!\n");printf("current pid = %d\n", getpid());if( (pid = fork()) > 0 ){g_global = 1;usleep(100);printf("child pid = %d\n", pid);printf("%d g_global = %d\n", getpid(), g_global);}else{g_global = 10;printf("parent pid = %d\n", getppid());printf("%d g_global = %d\n", getpid(), g_global);}return 0;
}

程序运行结果如下图所示

fork() 前,打印当前进程的 pid 为 6619

fork() 后,当前进程会创建出和自己一样的子进程,随后,父进程和子进程会同时运行,通过 fork() 的返回值可以判断出父进程和子进程,由于父进程 sleep 100us,所以子进程会先打印,然后父进程再打印

思考

如何理解 "每个 Linux 进程可以执行一个或多个程序"?

每个 Linux 进程 可以读取一个或多个程序的代码和数据,从而来执行程序

execve(...) 的工作方式

根据参数路径加载可执行程序

通过可执行程序信息构建进程数据,并写入当前进程

将程序执行位置重置到入口地址处 (即:main())

execve(...) 将重置当前进程空间 (代码 & 数据) 而不会创建新进程

execve 初探

helloworld.c

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>int main()
{printf("exec = %d, %s\n", getpid(), "Hello World!");return 0;
}

test.c

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>#define EXE "helloworld.out"int main()
{char* args[] = {EXE, NULL};printf("begin\n");printf("pid = %d\n", getpid());  execve(EXE, args, NULL);printf("end\n");return 0;
}

我们将 helloworld.c 编译为 helloworld.out,将 test.c 编译为 test.out,来查看运行结果

execve 不会创建新的进程,而是将当前进程的进程数据替换为 helloworld.out 的进程数据,并执行,所以执行完 helloworld.out后就结束了,不会打印 end 

我们可以 fork 子进程来执行 execve,这样当前进程的进程数据就不会被替换了

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>#define EXE "helloworld.out"int create_process(const char* pathname, char* const argv[])
{int ret = 0;if((ret = fork()) == 0){execve(pathname, argv, NULL);}return ret;
}int main()
{char* args[] = {EXE, NULL};printf("begin\n");printf("pid = %d\n", getpid());  printf("child pid = %d\n", create_process(EXE, args));printf("end\n");return 0;
}

程序执行结果如下图所示

通过 fork 子进程的方式来执行 execve,这样父进程的数据不会被替换,父进程成功打印出 end


http://www.ppmy.cn/news/457467.html

相关文章

OpenCV项目开发实战-- 将一个三角形变形为另一个三角形 ( C++ / Python )代码实现

文末附基于Python和C++两种方式实现的测试代码下载链接 图 1:左图中蓝色三角形内的所有像素都已转换为右图中的蓝色三角形。 在本教程中,我们将看到如何将图像中的单个三角形变形为不同图像中的另一个三角形。 在计算机图形学中,人们一直在处理扭曲三角形,因为任何 3D 表…

如何解压bz2后缀的压缩文件

.bz2 解压1&#xff1a;bzip2 -d FileName.bz2 解压2&#xff1a;bunzip2 FileName.bz2 压缩&#xff1a; bzip2 -z FileName .tar.bz2 解压&#xff1a;tar jxvf FileName.tar.bz2 #显示解压详细过程 或tar --bzip xvf FileName.tar.bz2 #不显示解压详细过程 压缩&#xff1a;…

解压后缀zip的压缩包

仅作参考 unzip jim.zip#jim.zip为需要解压的文件&#xff0c;解压到当前文件夹下

Windows11系统下解压文件后缀为.tar(.gz)的压缩文件

第一步&#xff1a;进入解压文件所在的当前文件夹内右键点击在终端打开 第二步&#xff1a;在终端内输入tar -zxvf xxx.tar.gz&#xff08;如果是.tar.gz文件就输入该行指令&#xff0c;如果是.tar文件就输入tar -zxvf xxx.tar指令&#xff0c;其中xxx为文件名&#xff09; 第三…

压缩文件的格式

任何一个文件存储在电脑上都有它的格式&#xff0c;例如文本格式像.txt .doc&#xff0c;图像格式 .jpg .tif .bmp等。 所有压缩文件也有压缩的格式&#xff0c;一般我们看到的压缩格式有 .rar .zip&#xff0c;但主要压缩的作用就是让某一个文件占用空间小点。比如原来的文件是…

压缩文件的后缀html,压缩文件的扩展名是什么

语音内容&#xff1a; 大家好&#xff0c;我是时间财富网智能客服时间君&#xff0c;上述问题将由我为大家进行解答。 压缩文件的扩展名是rar、zip、arj等。 简单来说&#xff0c;经过压缩软件压缩的文件叫压缩文件&#xff0c;压缩的原理是把文件的二进制代码压缩&#xff0c;…

在 linux 下如何解压扩展名为 xz 的文件

一些 Linux 用户喜欢使用 xz 压缩文件&#xff0c;因为这种无损压缩方式的压缩比率比 gzip 和 bizp2 高。对于扩展名为 xz 的压缩文件&#xff0c;我们需要先安装 xz 解压工具&#xff0c;然后使用 tar 命令来解压。具体操作如下。 安装 xz 解压工具包 在 Debian 和 Ubuntu 下…

linux下各种后缀名文件的压缩和解压缩

linux下压缩和解压缩 文件的后缀名为.tar时 1.在linux下压缩文件后缀名为.tar时使用的命令$ tar -cvf 压缩文件的名称 被压缩的文件或者文件夹demo:$ tar -cvf test.tar test 2..在linux下解压文件后缀名为.tar时使用的命令$ tar -xvf 压缩文件的名称 demo:$ tar -xvf 压缩文…