进程及从Linux分析进程
1.什么叫进程
1.1进程的概念
概念定义:进程即程序的一个执行实例,正在执行的程序等
从操作系统内核理解:进程即担当分配系统资源(CPU的时间、内存)的实体
从进程的实质来理解,进程 = 内核数据结构+程序的代码和数据。理解请见下文
1.2描述进程
进程信息被放在⼀个叫做进程控制块(PCB 即process control block)的数据结构中,可以理解为进程属性的集合。到Linux操作系统中描述进程的结构体叫task_struct。
进程的管理方法——先描述,再组织。即先将进程的属性用task_struct来描述,再统一管理进程。
2.观察一下进程
根目录中有一个名为proc的文件,期中储存了进程的相关信息
进入列出proc中的文件,这些数字即为进行中的进程的id
列出某个id进程的文件
1.将程序运行起来——>本质就是在系统中启动了一个进程
进程可分为
(1)执行完就退出的进程(如ls、pwd等指令)(2)一直执行不退出,直到用户退出——常驻进程
当我们写了一个死循环的程序后,以它的id命名的目录就会添加到/proc文件中,当此程序终止时(使用kill命令),在/proc中以它的id命名的目录就会被删除。
2.理解cwd、exe
由上文列出某个进程的文件中有一个名为cwd的文件,cwd即current work dir(当前工作目录),程序运行时的相对路径即由此确定。可以在程序中使用chdir函数更改cwd
exe即为进程对应程序。
3./proc不是磁盘级别的文件
/proc只是以文件形式存储在了磁盘中,以便观察,实际上进程的属性存储在内存中。
3.task_struct属性分类分类
3.1标示符
标示符:描述本进程的唯⼀标示符,⽤来区别其他进程。
可以使用ps命令可以打印当前进程的快照,可以展示一些属性如pid(自己的id)、ppid(父进程的id)、stat(进程的状态)
3.2使用系统调用,创建子进程
3.2.1.演示了子进程的创建
getpid、getppid为系统提供的接口,可以获取当前进程的pid、ppid,pid_t类型的定义包含在sys/types.h中,getpid、getppid包含在unistd.h中
fork函数也为系统提供的接口,可以创建一个子进程
以下代码为子进程创建的示例
#include<iostream>
#include<unistd.h>
#include<vector>
#include<sys/types.h>
using namespace std;
void prun(pid_t rid)
{
while(1)
{
cout<<"我是一个父进程,pid为:"<<getpid()<<" ,ppid为:"<<getppid()<<endl;
cout<<"fork返回id为:"<<rid<<endl;
sleep(2);
}
}
void run()
{
while(1)
{
cout<<"我是一个子进程,pid为:"<<getpid()<<" ,ppid为:"<<getppid()<<endl;
sleep(2);
}
}
int main()
{
cout<<"hello PCB"<<endl;
//while(1)
//{
// //cout<<"hello process!"<<endl;
// sleep(1);
//}
pid_t pid = fork();
if(pid != 0)
{
prun(pid);
}
else
{
run();
}
return 0;
}
3.2.2解释fork函数的特点
fork函数父进程返回id>0(子进程的pid),子进程返回id==0
父:子 = 1:n
即可以有多个子进程,但只能有一个父进程
fork()->两个进程 ->父子关系 ->一般而言,代码是共享的但数据各私有一份。(进程有很强的独立性,多个进程之间,运行时,互不影响,即使是父子)
3.2.3理解创建子进程——从系统接口上
在fork函数内部模拟如下
总结
1.fork()id返回值,父进程(subpid)、子(0)
2.fork有两个返回值
3.一个变量怎么会有两个不同的值?
--进程需要独立性
4.fork之后谁先运行,由OS调度器自主决定