我与Linux的爱恋:进程|进程的查看与管理|创建进程

news2024/9/23 7:33:56


外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

🔥个人主页guoguoqiang. 🔥专栏Linux的学习

Alt


文章目录

  • 一、进程的概念
    • 1.什么是进程
    • 2.`在这里插入代码片`多进程管理
    • 3.描述进程-PCB
  • 2.查看进程与管理进程
    • 1.使用指令查看进程
    • 2.通过系统调用函数查看pid
    • 3.杀进程
    • 4.ppid(父进程id)
    • 3.创建进程
    • 4.task_struct内容分类
    • 5.查看进程内容

在这里插入图片描述

一、进程的概念

1.什么是进程

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

简单来说,进程==PCB(进程控制块)+进程对应的代码和数据,一个进程对应一个PCB操作系统对进程的管理,最终变成对链表的增删查改。
注意:可执行程序加载到内存不是进程,只是进程对应的代码和数据

2.在这里插入代码片多进程管理

操作系统中可以存在大量的进程,操作系统需要管理这些进程,以确保系统资源(如CPU时间,内存等)的合理分配。管理进程的本质是对进程数据的管理

3.描述进程-PCB

进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合。课本上称之为PCB(process control block), Linux操作系统下的PCB是: task_struct

struct task_struct {
    volatile long state;
    void *stack;
    atomic_t usage;
    unsigned int flags;     
    unsigned int ptrace;
    unsigned long ptrace_message;
    siginfo_t *last_siginfo; 
    int lock_depth;         
    // ... 其他属性
};

在Linux中描述进程的结构体叫做task_struct。
task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息(如进程状态、优先级、程序计数器、内存指针、上下文数据、I/O状态信息和记账信息等)
所有运行在系统里的进程都以task_struct链表的形式存在内核里。

2.查看进程与管理进程

1.使用指令查看进程

ps指令:
语法 ps[选项]
功能:显示当前终端会话中属于当前用户的进程列表
选项:
在这里插入图片描述

常见格式: ps -axj |head -1 && ps -ajx |grep可执行文件
在这里插入图片描述
也可以通过系统文件然后用pid查看 ls /proc/
在这里插入图片描述

2.通过系统调用函数查看pid

操作系统对进程进行管理,但是用户不能直接访问操作系统,因此需要使用系统提供的系统调用函数来管理进程。
查看pid的函数为 getpid();返回值为pid_t
可以通过man getpid 查询
在这里插入图片描述
在这里插入图片描述
发现通过命令查和通过通过系统调用查看的结果一样

3.杀进程

方法1: crtl + c ;方法2: kill -9 pid
在这里插入图片描述
注意:kill掉任意一个进程不会影响另一个进程!!!(保证进程的独立性)

4.ppid(父进程id)

在这里插入图片描述
为什么进程每次启动pid会变,但是ppid不会变呢???

我们先查看一下父进程是什么,输入该命令: ps -axj | head -1 && ps -axj | grep ppid 通过查看可以看到该进程是bash进程(命令行解释器),因此就很好理解了。
在这里插入图片描述
当我们运行一个进程时,命令行解释器会把这个指令解释成bash的子进程。

接着再由这个bash的子进程执行对应的命令。

即:每一条命令被执行,都属于bash的子进程,只是子进程不一样。

为了更好看到执行程序与进程信息,可以使用shell脚本,隔一秒查一次进程

while : ; do ps ajx | head -1 && ps ajx | grep myprocess; sleep 1; done

3.创建进程

fork() 是 Unix 系统中用于创建新进程的系统调用。它会创建一个与当前进程几乎完全相同的新进程,新的进程称为子进程。父进程和子进程会继续从 fork() 调用的下一行代码开始执行。在这里插入图片描述

在 shell 中,你可以直接运行命令来创建进程。每个命令都会在系统中创建一个新进程。例如:

$ ls
$ gcc my_program.c -o my_program
$ ./my_program

这些命令分别创建了 ls、gcc 和 ./my_program 进程。每个命令的执行都涉及到创建一个新进程。

fork()的工作原理:
1.创建子进程

当进程调用 fork() 时,操作系统会创建一个新的进程,这个新的进程被称为子进程。子进程是父进程的几乎完整的拷贝,但有一些区别。
新进程会获得一个新的进程标识符(PID),这是与父进程不同的。

2.复制父进程的上下文

fork() 调用时,操作系统会复制父进程的内存空间、文件描述符、文件偏移量、信号处理器等信息到子进程中。这包括堆栈、代码段和数据段。
这称为“写时复制”(Copy-on-Write,COW)技术,实际上,操作系统在最初并不会立即复制内存中的所有数据,而是只在需要修改时才进行复制,以提高效率。

3.内存共享与复制

初始时,父进程和子进程共享相同的内存页。只有当其中一个进程试图修改这些页时,操作系统才会为该进程创建这些页的独立副本,这就是写时复制的机制。
这种机制可以节省内存和加快进程创建速度。

4.返回值

fork() 系统调用会在父进程和子进程中返回不同的值:
在父进程中,fork() 返回新创建的子进程的 PID。
在子进程中,fork()返回 0。
这个返回值可以用于区分父进程和子进程,进而决定不同的执行路径。

5.进程调度

在 fork() 之后,父进程和子进程将分别从 fork() 调用的下一行代码开始执行。操作系统的调度器会决定哪个进程先运行。

6.资源分配

子进程会继承父进程的所有资源描述符(如打开的文件描述符、信号处理器等),但这些描述符会有独立的引用计数。子进程和父进程的文件描述符指向同一个文件表项,因此对文件的读写操作可能会影响两个进程。

例子:

#include <stdio.h>    
#include <unistd.h>    
#include <sys/types.h>    
int main()    
{    
    fork();//创建进程    
    printf("hello world,pid: %d,ppid: %d\n",getpid(),getppid());//查看进程对应信息  
}

在这里插入图片描述

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

int main() {
    pid_t pid = fork();  // 创建一个新进程

    if (pid < 0) {
        // fork 失败
        perror("fork failed");
        return 1;
    } else if (pid == 0) {
        // 子进程执行的代码
        printf("This is the child process. PID: %d\n", getpid());
    } else {
        // 父进程执行的代码
        printf("This is the parent process. PID: %d, Child PID: %d\n", getpid(), pid);
    }

    return 0;
}

在这里插入图片描述
正常一个if在c语言中只会执行一次,而这里执行了两次。说明有两个进程。

#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
 
int main()
{
 
	printf("process is running,only me!,pid: %d\n", getpid());
	sleep(3);
	pid_t id = fork();
	if (id == -1) return -1; //进程创建错误直接退出
	else if (id == 0)
	{
		//child 子进程代码
		while (1)
		{
			printf("id: %d,I am child process,pid: %d,ppid: %d\n", id, getpid(), getppid());
			sleep(1);
		}
	}
	else
	{
		//parent 父进程代码
		while (1)
		{
			printf("id: %d,I am parent,pid: %d,ppid: %d\n", id, getpid(), getppid());
			sleep(2);
		}
	}
	return 0;
}

在这里插入图片描述
一次性创建多个进程

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
void RunChild()
{
 
	while (1)
	{
		printf("I am a child process,pid: %d,ppid: %d\n", getpid(), getppid());
		sleep(1);
	}
}
int main()
{
	int num = 5;
 
	while(num--)
	{
		pid_t id = fork();
		if (id == 0)
		{
			RunChild();//运行子进程代码
		}
		sleep(1);
	}
 
	while (1)
	{
		sleep(1);
		printf("I am parent,pid: %d,ppid: %d\n", getpid(), getppid());
	}
	return 0;
}

在这里插入图片描述
为了更好看到执行程序与进程信息,可以使用shell脚本,隔一秒查一次进程,且不查看grep进程信息。

while : ; do ps ajx | head -1 && ps ajx | grep myprocess | grep -v grep; sleep 1; done

-v是反向选择
子进程”在操作系统中扮演着重要的角色,它们的创建和使用有很多实际的需求和好处。下面是一些主要的原因和应用场景,解释了为什么要为什么要创建子进程:

  1. 任务分离和并行处理
    任务分离:通过创建子进程,可以将复杂的任务分解成多个独立的子任务,从而提高程序的结构化和可维护性。例如,在 Web 服务器中,主进程可以处理网络连接,而每个子进程可以处理单独的请求,这样可以避免主进程因为某个请求的处理而阻塞。

并行处理:子进程可以在多核处理器上并行执行任务,提高程序的执行效率。利用子进程并行处理多个计算密集型任务,可以显著提升性能。例如,科学计算中的大量数据处理可以通过多个子进程并行执行。

  1. 避免阻塞
    非阻塞操作:在许多应用程序中,某些操作可能会阻塞主进程的执行。通过创建子进程,主进程可以继续执行其他任务而不会被阻塞。例如,数据库操作或长时间运行的网络请求可以放在子进程中处理,以避免影响主进程的响应能力。
    权限限制:子进程可以以不同的用户权限运行,从而限制对系统资源的访问
  2. 资源隔离
    资源管理:子进程可以拥有独立的资源和内存空间,避免了不同任务之间的干扰。例如,在进行文件操作时,如果文件处理出现问题,子进程的崩溃不会影响主进程的运行,这有助于提高系统的稳定性和鲁棒性。
  3. 安全性和隔离
    安全隔离:通过子进程,系统可以将不同的任务隔离开来,避免潜在的安全风险。例如,浏览器通常会为每个标签页创建独立的子进程,这样即使某个标签页出现了问题,也不会影响其他标签页或浏览器的主进程。
  4. 提高响应能力
    多任务处理:在用户交互密集的应用中(例如图形用户界面应用程序),创建子进程可以让主进程保持响应性。子进程可以处理后台任务或长时间运行的计算,从而确保主界面不会因为这些任务而变得不响应。
  5. 简化编程模型
    简化设计:在一些系统设计中,通过子进程可以简化任务的设计和管理。子进程的创建和管理可以使得系统的设计更加模块化、清晰。例如,在 Unix 系统中,守护进程(daemon)通常通过子进程机制来运行后台服务。
  6. 进程生命周期管理
    灵活性:子进程的创建和管理提供了灵活的进程生命周期控制。父进程可以在子进程完成任务后进行必要的清理和资源回收,或者根据子进程的执行结果决定后续的操作。
    总结
    创建子进程在现代操作系统中是一个强大且灵活的机制,允许程序以高效和结构化的方式处理多任务、多线程和资源隔离等复杂问题。通过使用子进程,系统能够提高响应能力、并行处理任务、增加安全性以及简化编程模型,从而实现更高效和稳定的软件系统。

4.task_struct内容分类

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

5.查看进程内容

◉ls /proc/pid -d # 按照目录查看

◉ ls /proc/pid -l # 查看进程内容

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{
	while (1)
	{
		printf("I am process,pid: %d,ppid: %d\n", getpid(), getppid());
		sleep(1);
	}
	return 0;
}

在这里插入图片描述
cwd当前目录
exe对应的是可执行程序目录
1.如果我们在此处把可执行程序给删除,进程还会不会运行呢???

此处删除程序并不会造成影响,因为程序是加载到内存的,也就是内存拷贝了一份,这里是不会造成影响的,因为所占内存小,但如果内存过大运行就会出现问题

2.当前工作路径有什么用呢?

我们在C语言中学习文件操作,fopen(“log.txt”,“w”);默认是在当前目录创建文件,但是我们不一定每次都在当前目录创建文件,那怎么才能在其他目录下创建文件呢?

修改文件创建的路径,我们需要一个命令:chdir
在这里插入图片描述

#include<stdio.h>  
#include<unistd.h>  
   
int main()                                                                       
{  
  chdir("/home/gwq");//更改工作目录为/home/gwq
  FILE* pf = fopen("log.txt", "w");//创建文件  
  (void)pf;// ignore system warning   
  fclose(pf);  
   
  while (1)  
  {  
    printf("I am a process,pid: %d\n", getpid());      
    sleep(1);  
  }  
  return 0;  
}  

在这里插入图片描述
在这里插入图片描述
cwd当前目录 进程路径
exe对应的是可执行程序路径
因此我们对文件的理解不应该是在C语言上,而是应该在操作系统上

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2138987.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何在 Visual Studio Code 中反编译具有正确行号的 Java 类?

优质博文&#xff1a;IT-BLOG-CN 问题 我在 macOS 中使用 vscode 版本 1.92.2&#xff0c;并安装了Java 扩展包v0.29.0。当我打开command click或right click->Go to definition一个没有源代码的类时&#xff0c;vscode 会使用 FernFlower 反编译器打开 .class 文件。但…

一步一步自制py脚本并且并且修改为exe可执行文件教学外附带SHA-1解密exe文件资源

第一步&#xff1a;安装 Python 下载 Python&#xff1a;访问 Python 官网 下载并安装最新版本的 Python。安装时选择添加到环境变量 PATH&#xff1a;在安装过程中&#xff0c;确保勾选“Add Python to PATH”选项。 第二步&#xff1a;编写 Python 脚本 创建一个新的 Pyth…

HTB-Base(strcmp函数绕过、sudo -l提权)

前言 各位师傅大家好&#xff0c;我是qmx_07&#xff0c;今天给大家讲解Base靶场&#xff0c;起点内容到此完结 渗透过程 信息搜集 服务器开放了22SSH服务 和 80HTTP服务 目录爆破 通过目录扫描出/login 和/asserts文件夹 发现/login 拥有目录遍历漏洞login.php.swp 是使用…

Mysql_使用简介

课 程 推 荐我 的 个 人 主 页&#xff1a;&#x1f449;&#x1f449; 失心疯的个人主页 &#x1f448;&#x1f448;入 门 教 程 推 荐 &#xff1a;&#x1f449;&#x1f449; Python零基础入门教程合集 &#x1f448;&#x1f448;虚 拟 环 境 搭 建 &#xff1a;&#x1…

循环练习 案例

swich新特性 jdk12 穿透 逢七过 //含有七和被七整除舍去 public class test1 {public static void main(String[] args){for (int i 1; i <100 ; i) {if(i%70||i%107||i/107){continue;}System.out.println(i);}} } 求平方根 //输入大于2的整数&#xff0c;求平方根&…

AI基础 L22 Uncertainty over Time I 时间的不确定性

Time and Uncertainty 1 Time and Uncertainty States and Observations • discrete-time models: we view the world as a series of snapshots or time slices • the time interval ∆ between slices, we assume to be the same for every interval • Xt: denotes the se…

C++编译环境(IDE)推荐及安装

IDE是什么 嗨嗨嗨&#xff0c;我又来水博文了 今天来给大家推荐几款好用的IDE IDE是集成开发环境&#xff08;Integrated Development Environment&#xff09;的缩写&#xff0c;是一种软件应用程序&#xff0c;提供了用于软件开发的各种工具和功能&#xff0c;包括代码编辑…

windows C++ 并行编程-PPL 中的取消操作(一)

并行模式库 (PPL) 中取消操作的角色、如何取消并行工作以及如何确定取消并行工作的时间。 运行时使用异常处理实现取消操作。 请勿在代码中捕捉或处理这些异常。 此外&#xff0c;还建议你在任务的函数体中编写异常安全的代码。 例如&#xff0c;可以使用获取资源即初始化 (RA…

LidarView之定制版本号

介绍 LidarView软件需要关注2个版本号&#xff1a;1.Application版本号&#xff1b;2.安装包版本号 Application版本号 改变LV_VERSION_FULL可达到改变软件版本号的目的 SET(LV_VERSION_FULL "V1.3.0")标题栏版本号 关于对话框 安装包版本号 在Inno Setup Compi…

【退役之再次线上部署】Spring Boot + VUE + Nginx + MySQL

这篇博客写在凌晨 4 点 20 分&#xff0c;这个时候我刚线上部署完成 web 项目&#xff0c;自己写的全栈项目 这个点儿&#xff0c;也睡不着了&#xff0c;索性就写篇博客记录一下 一、踩坑实录 这个是 最重要的&#xff0c;所以写在前面 Nginx 配置文件 location location /a…

如何做系统架构?从动态系统思考的角度

在动态系统思考的背景下&#xff0c;系统架构不再只是一个静态的、结构化的设计&#xff0c;而是一个随着时间推移、基于不同要素互动产生涌现行为的动态过程。系统架构师的任务不仅仅是定义系统的形态和结构&#xff0c;更是通过剖析系统的互动网络、功能涌现和使用场景&#…

文章解读与仿真程序复现思路——电力系统自动化EI\CSCD\北大核心《计及抢修人员调度的配电网信息-物理协同恢复策略》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

个人随想-向量数据库,你到底应该选择谁?

随着大模型的新起&#xff0c;vectorstore这1、2年也非常的火。从以前只能用chroma到现在几十种向量数据库&#xff0c;选都选不过来。 以我接触过的很多公司来说&#xff0c;他们去选择向量数据库的时候&#xff0c;很多都和迷茫&#xff0c;不知道应该选择哪个向量数据库&am…

MySQl篇(数据类型)(持续更新迭代)

目录 常见类型一&#xff1a;数值类型 常见类型二&#xff1a;字符串类型 一、文本字符串类型 1. char & varchar 1.1. CHAR(M)类型 1.2. VARCHAR(M)类型 1.3. 两者应用 2. enum & set 二、二进制字符串类型 1. BINARY & VARBINARY类型 2. 二进制字符串和…

C++ IO框架

文章目录 I/O 复用概述I/O 模型一个输入操作的两个阶段 select 函数概述详细解析函数内容详解select总结 poll 函数概述详细解析函数内容详解 epoll 函数概述基础API注意事项总结一下select, poll, epoll的区别 Reactor 和 Proactor概述概念服务器连接多个客户端的业务场景解决…

【DVWA】——File Upload(文件上传)

&#x1f4d6; 前言&#xff1a;文件上传漏洞是由于对上传文件未作过滤或过滤机制不严&#xff08;文件后缀或类型&#xff09;&#xff0c;导致恶意用户可以上传脚本文件&#xff0c;通过上传文件可达到控制网站权限的目的。 目录 &#x1f552; 1. Low&#x1f552; 2. Mediu…

Window10安装多智能体强化学习平台(SMAC)

基本步骤可以参照博客&#xff1a;window10安装多智能体强化学习平台&#xff08;SMAC&#xff09;_conda如何安装smac库-CSDN博客 注意1&#xff1a;上面所涉及的python第三方库版本不一定要安装博客指定版本。 注意2&#xff1a;星际争霸需要安装国际服(国服不支持)&#x…

Redisson实现分布式锁(看门狗机制)

目录 可重入锁&#xff1a; 锁重试和看门狗机制&#xff1a; 主从一致性&#xff1a; 首先引入依赖&#xff0c;配置好信息 3.使用Redisson的分布式锁 可重入锁&#xff1a; 可重入锁实现是通过redsi中的hash实现的&#xff0c;key依旧是业务名称加id&#xff0c;然后第一个…

正式发售!《黑神话:悟空》背后的技术力量——UE5与实时云渲染

千呼万唤始出来&#xff0c;《黑神话&#xff1a;悟空》终于在今年8月发售了&#xff0c;相信大家都已经玩起来了&#xff01; 作为国产游戏的画质巅峰之作&#xff0c;《黑神话&#xff1a;悟空》凭借其令人叹为观止的画面质量和游戏体验&#xff0c;赢得了广泛的好评。这一切…

实时监控分析广告数据跳转统计平台源码

广告跳转实时分析页面统计系统&#xff0c;可选择生成html页面样式&#xff0c;可自定义设置页面域名后缀&#xff0c;可指定跳转指定网址&#xff0c; 可记录单个页面的访问记录&#xff0c;可对生成的单个链接进行备注&#xff0c;自定义等待时间进行跳转。 源码下载&#…