linux中进程相关概念(一)

什么是程序,什么是进程,有什么区别?

程序是静态的概念,当我们使用gcc xxx.c -o pro进行编译时,产生的pro文件,就是一个程序。
进程是程序的一次运行活动,通俗点就是说程序跑起来了就是进程。

如何查看系统中有哪些进程?

1.使用ps指令查看
实际工作中,配合grep来查找程序中是否存在某一个进程

ps -aux	//来查看整个系统中的进程
//但是在实际工作过程中,往往我们只需要查看某个进程的运行情况,此时可以用grep关键字
//比如我们需要查找init进程,通过grep过滤即可
ps -aux|grep init

2.使用top指令查看,类似windows任务管理器
在这里插入图片描述

什么是进程标识符?

每个进程都有一个非负整数表示唯一的id,叫做pid,类似身份证
pid=0;称为交换进程,作用是进程调度
pid=1;称为init进程,作用是系统初始化

getpid

可以通过getpid获取进程的pid号
#include <sys/types.h>
#include <unistd.h>

pid_t getpid(void);

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>int main(){//pid_t getpid(void);pid_t pid;pid = getpid();printf("my pid is: %d\n",pid);while(1);return 0;
}

在这里插入图片描述
在这里插入图片描述

什么叫父进程,什么叫子进程?

进程A创建了进程B
那么A叫做父进程,B叫做子进程,父子进程是相对的概念,理解为人类中的父子关系

C程序的存储空间是如何分配的?

代码段(正文):if else 、swtich case等算法代码段。
初始化数据段:初始化过的数据。
非初始化数据段(bss段):未被初始化的数据。
堆:存放malloc的数据。
栈:函数递归调用返回地址,局部变量等数据。
命令行参数和环境变量:argc,argv等

编程创建进程

fork

#include <unistd.h>

pid_t fork(void);


#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>int main(){//pid_t getpid(void);pid_t pid;pid = getpid();fork();printf("my pid is: %d\n",pid);return 0;
}

运行这段代码,会发现返回两个pid
my pid is: 12296
my pid is: 12296
在fork之前有一个进程,通过fork创建了一个进程,我们可以理解为第一个进程printf了一次,第二个进程也printf了一次,因此会出现两个pid号。我们可以通过getpid的方法来找出新进程的pid:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>int main(){//pid_t getpid(void);pid_t pid;pid = getpid();fork();printf("my pid is: %d,current pid is:%d\n",pid,getpid());return 0;
}

运行结果:
my pid is: 12376,current pid is:12376
my pid is: 12376,current pid is:12377
第一行的两个pid都相等,代表了这是原先的进程,第二行打印出一个新的pid,说明这是我们新创建的进程。

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>int main(){//pid_t getpid(void);pid_t pid;pid = getpid();fork();if(pid == getpid()){printf("this is father process,father pid is:%d\n",pid);}else{printf("this is son process,sun pid is:%d\n",getpid());}return 0;
}

运行结果:
this is father process,father pid is:12437
this is son process,sun pid is:12438
说明子进程和父进程都会执行这段代码,只不过两个进程会进入不同的分支。

研究fork的返回值

返回值为0说明为子进程
返回值大于0说明为父进程,并且值为子进程的pid号


#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>int main(){//pid_t getpid(void);pid_t pid;printf("current pid is:%d\n",getpid());pid = fork();if(pid > 0){printf("this is father process,father pid is:%d\n",getpid());}else if(pid == 0){printf("this is son process,sun pid is:%d\n",getpid());}return 0;
}

运行结果:
current pid is:12567
this is father process,father pid is:12567
this is son process,sun pid is:12568

fork时发生了什么事情

以前的版本,我们在fork之后会将原先的地址空间全部拷贝一份,而现在的版本我们采用写时拷贝,只有在我们在子进程中修改每一个参数的值的时候,才从父进程中拷贝一份这个数据到子进程地址空间去。

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>int main(){//pid_t getpid(void);pid_t pid;int data = 10;printf("current pid is:%d\n",getpid());pid = fork();if(pid > 0){data+=10;printf("this is father process,father pid is:%d,data=%d\n",getpid(),data);}else if(pid == 0){printf("this is son process,sun pid is:%d,data=%d\n",getpid(),data);}return 0;
}

运行结果:
current pid is:12889
this is father process,father pid is:12889,data=20
this is son process,sun pid is:12890,data=10

创建子进程的目的

应用场景1. 创建子进程响应客户端请求

父进程自身作为一个服务器,当收到一个客户端发来的请求时,就fork一个子进程来响应这个请求。
我们可以用while循环来模拟一下这个过程:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>int main(){//pid_t getpid(void);pid_t pid;int data;while(1){printf("please input a data\n");scanf("%d",&data);if(data == 1){pid = fork();if(pid > 0){}else if(pid == 0){while(1){printf("do net request,pid=%d\n",getpid());sleep(3);}}}else{printf("wait,no request\n");}}return 0;
}

在这里插入图片描述
ps -aux|grep myPro
Warning: bad ps syntax, perhaps a bogus ‘-’? See http://procps.sf.net/faq.html
CLC 13052 0.0 0.0 4164 352 pts/2 S+ 22:09 0:00 ./myPro
CLC 13053 0.0 0.0 4164 96 pts/2 S+ 22:09 0:00 ./myPro
CLC 13054 0.0 0.0 4164 96 pts/2 S+ 22:09 0:00 ./myPro
CLC 13055 0.0 0.0 4164 96 pts/2 S+ 22:09 0:00 ./myPro
CLC 13058 0.0 0.0 13588 940 pts/3 S+ 22:10 0:00 grep --color=auto myPro
可以看到父进程为13052,而53,54,55都是我们创建的子进程来响应客户端的请求。

应用场景2. 一个进程要执行一个不同的程序

这对shell时常见的情况。在这种情况下,子进程从fork返回后立即调用exec,在后续会学习该方面知识。

fork总结

由fork创建的新进程被称为子进程。fork函数被调用一次,但返回两次。两个返回的唯一区别是子进程的返回值是0,而父进程的返回值则是新子进程的进程pid。将子进程id返回给父进程的理由是:因为一个进程的子进程可以有多个,并且没有一个函数使一个进程可以获得其所有子进程的pid。fork使子进程得到返回值0的理由是:一个进程只会有一个父进程,所以子进程总是可以调用getpid以获得其父进程的进程id。(进程id 0总是由内核交换进程使用,所以一个子进程的进程id不可能为0)。
子进程和父进程继续执行fork之后的指令。子进程获得父进程的数据空间、堆栈副本。注意,这是子进程所拥有的副本。父子进程并不共享这些存储空间部分,父子进程共享正文段(代码段)。
后来采用写时拷贝,只有修改一块的变量才会复制那一块到自己的内存空间中。

vfork

vfork与fork的区别:
①vfork直接使用父进程存储空间,不拷贝。
②vfork保证子进程先运行,当子进程调用exit推出后,父进程才执行。

例如:
普通的fork创建进程:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>int main(){//pid_t getpid(void);pid_t pid;pid = fork();if(pid > 0){while(1){printf("this is father process,father pid is:%d\n",getpid());sleep(1);}}else if(pid == 0){while(1){printf("this is son process,son pid is:%d\n",getpid());sleep(1);}}return 0;
}

运行结果:
this is father process,father pid is:13256
this is son process,son pid is:13257
this is son process,son pid is:13257
this is father process,father pid is:13256
this is father process,father pid is:13256
this is son process,son pid is:13257
this is father process,father pid is:13256
this is son process,son pid is:13257
父子进程都会运行。
当我们将fork改为vfork时:
运行结果:
this is son process,son pid is:13370
this is son process,son pid is:13370
this is son process,son pid is:13370
this is father process,father pid is:13369
this is father process,father pid is:13369
this is father process,father pid is:13369
this is father process,father pid is:13369
this is father process,father pid is:13369
this is father process,father pid is:13369
先运行子进程,当子进程exit后,才运行父进程。并且子进程直接使用父进程的存储空间,不拷贝,比如我们创建一个cnt,在子进程中对cnt进行累加,当cnt为3时,我们退出进程,此时在父进程中输出cnt的值为3。

进程退出

正常退出

1.main函数调用return
2.进程调用exit(),标准C库
3.进程调用_exit()或者_Exit(),属于系统调用
4.进程最后一个线程返回
5.最后一个线程调用pthread_exit

异常退出

1.调用abort
2.当进程收到某些信号时,如ctrl+C
3.最后一个线程取消(cancellation)请求做出响应

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【springboot基础】如何搭建一个web项目?

正在学习springboot&#xff0c;还是小白&#xff0c;今天分享一下如何搭建一个简单的springboot的web项目&#xff0c;只要写一个类就能实现最基础的前后端交互&#xff0c;实现web版helloworld &#xff0c;哈哈&#xff0c;虽然十分简陋&#xff0c;但也希望对你理解web运作…

网络新手如何上手水牛社软件?我的建议与看法

水牛社是一款专为电脑用户设计的软件&#xff0c;拥有明确的著作权&#xff0c;其核心功能在于发布和整合各类网络活动任务资源、教程等&#xff0c;内容多元且不设固定分类。其靠谱程度取决于你对软件的了解程度和个人需求的适配性。 软件内部包含五个主要栏目&#xff0c;大…

(八)JSP教程——application对象

application对象是一个比较重要的对象&#xff0c;服务器在启动后就会产生这个application对象&#xff0c;所有连接到服务器的客户端application对象都是相同的&#xff0c;所有的客户端共享这个内置的application对象&#xff0c;直到服务器关闭为止。 可以使用application对…

AlphaFold3: Google DeepMind的的新突破

AlphaFold 3的论文今天在Nature期刊发表啦!这可是AI在生物领域最厉害的突破的最新版本。AlphaFold-3的新招就是用扩散模型去"画出"分子的结构。它一开始先从一团模模糊糊的原子云下手,然后慢慢透过去噪把分子变得越来越清楚。 Alphafold3 我们活在一个从Llama和Sora那…

STM32理论 —— μCOS-Ⅲ(新)

文章目录 1. 任务调度器1.1 抢占式调度 μCos-Ⅲ全称是Micro C OS Ⅲ&#xff0c;由Micriμm 公司发布的一个基于C 语言编写的第三代小型实时操作系统(RTOS)&#xff1b; RTOS 与裸机相比最大的优势在于多任务管理与实时性&#xff0c;它提供了多任务管理和任务间通信的功能&a…

如何切换PHP版本

如果服务器上安装了多个php&#xff0c;可能会导致默认的php版本错误&#xff0c;无法启动swoole等服务&#xff0c; 查看命令行的php版本方法&#xff1a;https://q.crmeb.com/thread/9921 解决方法如下&#xff0c;选一个即可&#xff1a; 一、切换命令行php版本&#xff…

Zabbix5.0——安装与部署

目录 一、zabbix-server(192.168.206.134) 监控方 1. 环境准备 2.安装zabbix 2.1 准备zabbix-repo 2.2清理缓存 2.3安装zabbix主包&#xff08;服务器和代理&#xff09; 2.4安装zabbix前端包 3. 数据库安装 3.1 授权zabbix账号 3.2导入数据库&#xff08;初始化zabbix&#x…

震惊,现在面试都加科技与狠货了

震惊&#xff0c;现在面试都加科技与狠货了 生成式AI盛行的现在&#xff0c;程序员找工作变容易了吗我和老痒喝着大酒&#xff0c;吃着他的高升宴&#xff0c;听他说他面试的各种细节&#xff0c;老狗我只恨自己动作慢了一步&#xff0c;不然现在在那侃侃而谈的就是我了。 面试…

Unity 修复Sentinel key not found (h0007)错误

这个问题是第二次遇到了&#xff0c;上次稀里糊涂的解决了&#xff0c;也没当回事&#xff0c;这次又跑出来了&#xff0c;网上找的教程大部分都是出自一个人。 1.删除这个路径下的文件 C:\ProgramData\SafeNet Sentinel&#xff0c;注意ProgramData好像是隐藏文件 2.在Windows…

若依框架dialog弹窗取消点击空白出关闭

如果想全局取消的话就找到main.js在里面加上下面的一行代码&#xff0c;添加完成之后记得清楚浏览器缓存重新加载js文件。 Element.Dialog.props.closeOnClickModal.default false;如果想指定某个弹窗取消点击空白处关闭&#xff0c;那么就找到那个弹窗加上。添加完毕之后刷新…

小程序如何注销

随着移动互联网的深入发展&#xff0c;管控也越来越严格。现在小程序都要求进行ICP备案&#xff0c;不管是新注册的还是以往注册的。很多商家的小程序本身处于无运营状态&#xff0c;现在要求备案&#xff0c;还不如直接注销。下面&#xff0c;将详细介绍小程序注销的步骤和注意…

C++ 直接初始化 和 拷贝初始化 的区别

参考链接&#xff1a;https://www.jb51.net/article/54773.htm这篇文章主要介绍了C直接初始化与复制初始化的区别深入解析,是很多C初学者需要深入了解的重要概念,需要的朋友可以参考下https://www.jb51.net/article/54773.htm