深入解析进程:探索计算机并发世界的核心机制

news2024/11/27 21:44:24
  • (꒪ꇴ꒪ ),Hello我是祐言QAQ
  • 我的博客主页:C/C++语言,Linux基础,ARM开发板,软件配置等领域博主🌍
  • 快上🚘,一起学习,让我们成为一个强大的攻城狮!
  • 送给自己和读者的一句鸡汤🤔:集中起来的意志可以击穿顽石!
  • 作者水平很有限,如果发现错误,可在评论区指正,感谢🙏


一、进程的概念

1.1 概念

        进程是操作系统中的核心概念之一,它代表了一个正在执行的程序实例。每个进程都有自己独立的内存空间,包括代码、数据和执行上下文。进程能够并发地执行,它是操作系统中多任务处理(资源分配)的基本单位

1.2 进程控制块(PCB)

        进程控制块是操作系统内部用来管理进程的数据结构。它包含了进程的各种信息,如进程状态、程序计数器、寄存器状态、内存分配情况等。PCB允许操作系统在不同进程之间切换,从而实现多任务处理。

 

二、进程的组织方式

2.1 父子进程关系

        进程可以通过父子关系来组织。一个进程可以创建新的子进程,子进程与父进程共享某些资源。子进程在创建后可以独立运行,拥有自己的进程ID。此外还拥有如下的一些特点:

        (1)查看进程树,以树形图显示进程: pstree;

        (2)除了系统初始init进程以外,任何进程都必须有父进程;

        (3)如果一个进程的父进程死掉,那么这个进程就会被系统分配一个默认父进程给它。

2.2 进程运行

        进程可以在不同的状态之间切换,如运行状态、就绪状态和阻塞状态。操作系统的调度算法决定了哪个进程在特定时间片段内执行。

        (1)前台进程: ./程序文件名;

        (2)后台进程:    ./程序文件名 &;

        (3)前台进程可以直接用ctrl + c关闭,后台进程不行,我们可以用 kill <进程号>关闭该进程。

        值得注意的是:linux系统中每一个进程都有父进程,当这个进程的父进程死掉,子进程如果没有跟着父进程一起死掉就变成孤儿进程,但是linux不允许,它会将这个进程作为一个特殊进程(类似孤儿院)的子进程。

2.3 查看正在运行的进程

        操作系统提供了工具来查看当前正在运行的进程,如ps命令。这可以帮助您监控系统中正在执行的任务。一些常用的后缀项如下:

        -f  查看更多信息;

        -u  显示更多信息(和f显示的信息不一样);

        -a  显示所有用户的所有进程;

        -x  显示无终端的进程;

        -e  显示所有进程;

        ps -ef  显示系统中所有的进程以及相关的详细信息;

 

2.4 终止进程

        进程可以通过发送终止信号来结束自己的执行,或者被其他进程终止。终止时,操作系统会释放进程占用的资源。常用命令为:

        kill <进程号>

        kill -9 <进程号>

 

2.5 动态显示正在运行的进程

        通过周期性地查询进程信息并显示在屏幕上,您可以实时监控系统中正在运行的进程,了解系统负载情况。(类似Windows的任务管理器),使用的命令为top

  top 是一个强大的工具,可以帮助您监控系统性能、查看进程信息以及定位资源瓶颈。通过实时的信息更新,可以更好地了解系统的运行情况。如有需要,您还可以通过命令行中的帮助文档(man top)来了解更多使用选项。

        该界面提供了一些重要的信息:

  • Tasks: 当前运行的任务数,包括运行中、睡眠中、停止等状态的任务;
  • %Cpu(s): CPU的使用率分布,包括用户态、系统态、空闲等;
  • KiB Mem: 内存使用情况,包括总内存、空闲内存、已使用内存和缓存;
  • KiB Swap: 交换空间使用情况,包括总交换空间、空闲交换空间和已使用交换空间。

       如果你想退出呢, 可以使用 q来退出 top 命令,或者使用 Ctrl+C 组合键来终止命令的执行。

三、 进程的状态

        进程的状态包括执行太、暂停态、僵尸态等。了解这些状态可以帮助理解进程的行为以及操作系统是如何管理它们的。

四、 进程相关函数

4.1 获取进程ID和父进程ID

        通过调用相应的函数,您可以获取当前进程的ID以及父进程的ID。

#include <unistd.h>

#include <sys/types.h>

pid_t getpid(void);//获取当前进程的进程号

pid_t getppid(void);//获取当前进程的父进程号

         代码:

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

int main() {
    pid_t child1, child2;

    child1 = fork(); // 创建子进程1

    if (child1 == 0) {
        // 子进程1
        printf("子进程1 - PID: %d, 其父进程PID: %d\n", getpid(), getppid());

        child2 = fork(); // 在子进程1中创建子进程2

        if (child2 == 0) {
            // 子进程2
            printf("子进程2 - PID: %d, 其父进程PID: %d\n", getpid(), getppid());
        }
    }

    return 0;
}

4.2 创建进程(fork)

   fork函数用于创建一个新的子进程,子进程是父进程的副本,包括内存内容和程序计数器。

#include <unistd.h>
pid_t fork(void);
返回值:
    在父进程中,返回值大于0,表示创建的子进程的进程号
    在子进程中,返回值等于0
    进程创建失败,返回值等于-1,并带有errno
备注:该函数执行成功之后,将会产生一个新的子进程,在新的子进程中其返回值为 0,在原来的父进程中其返回值为大于 0 的正整数,该正整数就是子进程的 PID  
         
另一个创建进程的函数:
#include <sys/types.h>
#include <unistd.h>

pid_t vfork(void);
返回值:
    在父进程中,返回值大于0,表示创建的子进程的进程号
    在子进程中,返回值等于0
    进程创建失败,返回值等于-1,并带有errno
区别:
        fork:
        1、函数调用之后,在下一行父子进程执行的时候,父进程比子进程先执行,但是不是百分之百,
        2、父子进程不共享内存,子进程更改数据,父进程不会受影响
        vfork:
        1、函数调用之后,在下一行父子进程执行的时候,子进程永远比父进程先执行,子进程要有退出,父进程才会执行
        2、父子进程共享内存,子进程更改数据,父进程会受影响

4.3 exec函数簇

   exec函数簇允许一个进程加载并运行一个新的程序。这使得进程能够动态改变执行的代码。

#include <unistd.h>
int execl(const char *path, const char *arg, ...);
int execv(const char *path, char *const argv[ ]);
int execle(const char *path, const char *arg, ..., char * const envp[ ]);

int execlp(const char *file, const char *arg, ...);
int execvp(const char *file, char *const argv[ ]);
int execvpe(const char *file, char *const argv[ ],char *const envp[ ]);

参数列表:
    path 即将被加载执行的 ELF 文件或脚本的路径;
    file 即将被加载执行的 ELF 文件或脚本的名字;
    arg 以列表方式罗列的 ELF 文件或脚本的参数;
    argv 以数组方式组织的 ELF 文件或脚本的参数;
    envp 用户自定义的环境变量数组。
备注:
    1.函数名带字母 l 意味着其参数以列表(list)的方式提供;
    2.函数名带字母 v 意味着其参数以矢量(vector)数组的方式提供;
    3.函数名带字母 p 意味着会利用环境变量 PATH 来找寻指定的执行文件;
    4.函数名带字母 e 意味着用户提供自定义的环境变量。

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

int main(int argc, char const *argv[])
{
	printf("进程开始运行\n");

	char *ar[] = {"./hello", NULL};

	pid_t x = fork();//调用fork创建子进程,执行成功之后,在下一行开始有一个父进程和子进程,两个进程
	if (x == -1)
	{
		perror("fork");
	}
	if (x == 0)
	{
		//让子进程执行当前路径下的hello
		execv("./hello", ar);
		// execvp("./hello", ar);
	}
	if (x > 0)
	{
		printf("父进程正在运行\n");
		sleep(1);
		printf("父进程结束运行\n");
	}
	return 0;
}

4.4 程序退出

        进程可以通过调用exit函数来正常退出,释放其占用的资源。另外,进程也可以通过异常或信号被强制终止。

(1)return 关键字:函数退出,当return放在main函数的时候,也表示程序退出。

(2)exit() 函数

#include <stdlib.h>

void exit(int status);

参数列表: status 子进程的退出值

(3)_exit()函数

#include <unistd.h>

void _exit(int status);

参数列表: status 子进程的退出值

值得注意的是:

        1.如果子进程正常退出,则 status 一般为 0;

        2.如果子进程异常退出,则 statuc 一般为非 0;

        3.exit()退出时,会自动冲洗(flush)标准 IO 总残留的数据到内核;

        4.如果进程注册 了“退出处理函数”还会自动执行这些函数。而_exit( )会直接退出。

(4) 程序退出处理函数注册

        在 <stdlib.h> 头文件中,提供了 atexit 函数,用于注册在程序退出时执行的函数。函数原型如下:

int atexit(void (*function)(void));

        参数 function 是一个指向返回类型为 void,参数列表为空的函数的指针。当程序退出时,注册的函数会被调用,它可以用来执行清理操作,释放资源等。

4.5 等待子进程退出/状态变化

        在 <sys/wait.h> 头文件中,提供了两个用于等待子进程退出或状态变化的函数:waitwaitpid

        (1)wait 函数

pid_t wait(int *stat_loc);

参数 stat_loc 是一个指向整数的指针,用于存储子进程的退出状态。

        (2)waitpid 函数

pid_t waitpid(pid_t pid, int *stat_loc, int options);

  • pid:等待的目标进程ID。根据不同值的含义,可以等待不同的子进程。
  • stat_loc:一个指向整数的指针,用于存储子进程的退出状态。
  • options:附加选项,例如使用 WNOHANG 可以使函数变为非阻塞。

        这两个函数在等待子进程退出或状态变化时非常有用,可以帮助父进程处理子进程的生命周期。返回值为子进程的ID,表示成功等待到子进程的状态变化。如果设置了 WNOHANG 选项且状态尚未改变,则 waitpid 可以返回0。如果失败,返回-1。

五、同步与互斥

        在多进程编程中,同步(Synchronization)和互斥(Mutual Exclusion)是两个重要的概念,用于确保多个进程之间的正确协作和资源访问。

1.同步(Synchronization)

        同步是指多个进程之间通过某种机制来协调它们的行为,以便按照期望的顺序执行,避免产生竞争条件和不一致性。同步的目的是为了确保进程间的协作和有序执行,以避免不确定性和数据损坏。

        在多进程编程中,可以使用各种同步机制来实现同步,如信号量、互斥锁、条件变量等。这些机制可以确保进程按照特定的顺序执行,以达到预期的结果。

2.互斥(Mutual Exclusion)

        互斥是一种同步机制,用于确保在同一时刻只有一个进程可以访问共享资源。这意味着在一个进程访问共享资源时,其他进程必须等待,直到该进程释放资源。

        互斥通常通过互斥锁(Mutex)来实现。当一个进程获取了互斥锁后,其他进程必须等待,直到该进程释放锁。这样可以避免多个进程同时修改共享资源导致数据不一致的问题。

        更多C语言Linux系统ARM板实战数据结构相关文章,关注专栏:

   手撕C语言

            玩转linux

                    脚踢数据结构

                            6818(ARM)开发板实战

📢写在最后

  • 今天的分享就到这啦~
  • 觉得博主写的还不错的烦劳 一键三连喔~
  • 🎉感谢关注🎉

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

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

相关文章

kafka集群之kraft模式

一、概要 Kafka作为一种高吞吐量的分布式发布订阅消息系统&#xff0c;在消息应用中广泛使用&#xff0c;在Kafka2.8之前&#xff0c;Kafka强依赖zookeeper&#xff0c;这也导致当Zookeeper集群性能发生抖动时&#xff0c;Kafka的性能也会收到很大的影响。2.8版本之后&#xf…

pd.cut()函数--Pandas

1. 函数功能 将连续性数值进行离散化处理&#xff1a;如对年龄、消费金额等进行分组 2. 函数语法 pandas.cut(x, bins, rightTrue, labelsNone, retbinsFalse, precision3, include_lowestFalse, duplicatesraise, orderedTrue)3. 函数参数 参数含义x要离散分箱操作的数组&…

ES6 新特性

&#x1f384;欢迎来到边境矢梦的csdn博文&#x1f384; &#x1f384;本文主要梳理前端技术的JavaScript的知识点ES6 新特性文件上传下载&#x1f384; &#x1f308;我是边境矢梦&#xff0c;一个正在为秋招和算法竞赛做准备的学生&#x1f308; &#x1f386;喜欢的朋友可以…

ardupilot开发 --- EKF篇

状态估计的算法发展 参数调试 AHRS_EKF_USE: set to “1” to use the EKF, “0” to use DCM for attitude control and inertial nav (Copter-3.2.1) or ahrs dead reckoning (Plane) for position control. In Copter-3.3 (and higher) this parameter is forced to “1” …

Maven报错 [ERROR] Malformed \uxxxx encoding.

IDEA刷新项目&#xff0c;报错[ERROR] Malformed \uxxxx encoding. 现象 1.控制台报错 [ERROR] Malformed \uxxxx encoding.2.项目代码大部分爆红 3.Pom文件不爆红 4.IDEA未能构建Dependencies 尝试清除IDEA缓存无效&#xff0c;重新克隆项目无效&#xff0c;更换低版本mav…

【MySQL】3、MySQL的索引、事务、存储引擎

create table class (id int not null,name char(10),score decimal(5,2)); insert into class values (1,zhangsan,80.5); update class set namewangwu,passwd123 where id2; select * from class where id2; drop 索引的概念 是一种帮助系统&#xff0c;能够更快速的查询信…

并发编程篇

并发编程篇 线程基础 线程和进程的区别 面试官&#xff1a; 说一下线程和进程的区别&#xff1f; 候选人&#xff1a; 嗯&#xff0c;好~ 进程是正在运行程序的实例&#xff0c;进程中包含了线程&#xff0c;每个线程执行不同的任务不同的进程使用不同的内存空间&#xf…

elementplus实现左侧菜单栏收缩与展开

1.页面结构 Home.vue下包含aside.vue和menu.vue 2.TAside.vue el-menu左侧菜单栏显示 注意&#xff1a; 要使用收缩与展开&#xff0c;el-aside必须设置width"collapse"&#xff0c;否则收缩展开会出现收缩后&#xff0c;el-aside宽度不变窄需要使用动态改变展开收…

微信商城小程序的特点以及功能都有什么?

在移动互联网时代&#xff0c;微信商城小程序已成为许多企业开展电商业务的重要工具。通过微信商城小程序&#xff0c;用户可以方便地在微信平台上浏览商品、下单购买、进行支付等操作。为了开发一款成功的微信商城小程序&#xff0c;既需要专业性&#xff0c;又需要思考深度的…

高速公路自动驾驶汽车超车控制方法研究

目录 摘要 ............................................................................................................ I Abstract ...................................................................................................... II 目录 ...............…

【Python】python 打印本地代理

前言 在 Python 中&#xff0c;如果需要访问被墙的网站或者需要隐藏本机 IP 地址&#xff0c;可以通过使用代理服务器来实现。本文将介绍如何打印本地代理的方法&#xff0c;并提供相应的代码和实例。 一、什么是代理服务器 代理服务器&#xff08;Proxy Server&#xff09;是…

AxureRP制作静态站点发布互联网,内网穿透实现公网访问

AxureRP制作静态站点发布互联网&#xff0c;内网穿透实现公网访问 文章目录 AxureRP制作静态站点发布互联网&#xff0c;内网穿透实现公网访问前言1.在AxureRP中生成HTML文件2.配置IIS服务3.添加防火墙安全策略4.使用cpolar内网穿透实现公网访问4.1 登录cpolar web ui管理界面4…

Django(9)-表单处理

django支持使用类创建表单实例 polls/forms.py from django import forms class NameForm(forms.Form):your_nameforms.CharField(label"Your name",max_length100)这个类创建了一个属性&#xff0c;定义了一个文本域&#xff0c;和它的label和最大长度。 polls/vi…

抖音矩阵,矩阵账号开发,抖音矩阵源码搭建

抖音矩阵&#xff0c;矩阵账号开发&#xff0c;抖音矩阵源码搭建&#xff1a; 1、账号矩阵系统搭建首先需要注意的是支持多平台&#xff0c;多账号&#xff0c;可以实现流量互通&#xff0c;账号矩阵多个账号联动形成账号矩阵形式分发开发。 2、账号矩阵系统需要可以查看分发…

尚硅谷宋红康MySQL笔记 10-13

是记录&#xff0c;我不会记录的特别详细 第10章 创建和管理表 标识符命名规则 数据库名、表名不得超过30个字符&#xff0c;变量名限制为29个只能包含 A–Z, a–z, 0–9, _共63个字符数据库名、表名、字段名等对象名中间不要包含空格同一个MySQL软件中&#xff0c;数据库不能…

【C++入门】new和delete(C/C++内存管理)

目录 1.C/C内存分布2.C语言中动态内存管理方式3.C内存管理方式3.1new/delete操作内置类型3.2new和delete操作自定义类型 4.operator new与operator delete函数5.new和delete的实现原理5.1内置类型5.2自定义类型 6.malloc/free和new/delete的区别7.定位new表达式&#xff08;了解…

小程序开发之登录授权

小程序开发登录授权流程 看懂这张图登录授权就没问题了&#xff08;哈哈哈哈哈&#xff09; 说明&#xff1a; 调用 wx.login() 获取 临时登录凭证code &#xff0c;并回传到开发者服务器。 调用 auth.code2Session 接口&#xff0c;换取 用户唯一标识 OpenID 和 会话密钥 sess…

Jmeter(三十):并发测试(设置集合点)

集合点:让所有请求在不满足条件的时候处于等待状态。 如:我集合点设置为50,那么不满足50个请求的时候,这些请求都会集合在一起,处于等待状态,当达到50的时候,就一起执行。从而达到并发的效果。 那么Jmeter中可以通过同步定时器 Synchronizing Timer 来完成。 Number …

数学系硕士研究生的科研过程——PDE约束下含参优化控制问题的深度学习算法

笔者今天上午收到了之前北大课题组老板的通知&#xff0c;得知研究生期间和学长合作的论文终于被siam接收&#xff0c;终于为自己研究生涯画上了一个句号。这里打算分享一下个人的科研过程以及这篇论文的工作&#xff0c;即将读研或者打算读研的同学或许可以从中获得益处。论文…

Jumpserver堡垒机管理(安装和相关操作)-------从小白到大神之路之学习运维第89天

第四阶段 时 间&#xff1a;2023年8月28日 参加人&#xff1a;全班人员 内 容&#xff1a; Jumpserver堡垒机管理 目录 一、堡垒机简介 &#xff08;一&#xff09;运维常见背黑锅场景 &#xff08;二&#xff09;背黑锅的主要原因 &#xff08;三&#xff09;解决背黑…