一、进程概念(进程又称为任务)
(1)哲学(^_^)概念:进程就是一个正在执行的程序,进程存在于内存,一个可执行程序从在于磁盘被操作系统执行时加载到内存执行
(2)我们的理解:进程就是一个正在执行的程序,它的属性被包含在一个叫进程控制块的数据结构中(PCB),PCB就是进程属性的集合,而在Linux操作系统中PCB是task_struct
注:task_struct只是PCB的一种,和我们之前学过的命令行解释器bash/shell是一个概念,王婆和媒婆的关系
总结:从用户角度来看,进程是一个正在执行的程序。在操作系统看来,它需要管理进程,需要先组织然后描述进程。
二、操作系统管理
管理:(1)将进程描述起来(task_struct)
(2)将很多个进程管理起来(双向链表)
即、我们需要每一个进程的PCB申请一块内存,在链表上面进行插入,即新的进程。如果进程结束也就是在链表上对该进程对应的PCB释放。
三、描述进程
task_struct内容
1. 进程id(process id)pid:每一个进程都有唯一的一个标识符,用来区别其他的进程
2. 内存指针:找到进程所对应的代码和代码依赖的数据在哪
补充一个概念:
并行:任务在同一时间运行(多核处理器)
并发:两个任务可以再重叠的时间段内启动,运行;
1个cpu同一时间只能处理一个进程而且执行速度非常快,所以采用并发的方式快速调度执行进程,宏观是多个进程同时执行,微观是有先后顺序,称为优先级;
3. 辅助操作系统对进程调度的属性
(1)优先级:被调度的进程在cpu上执行的先后顺序
(2)上下文数据:包含每个进程执行过的、执行时的以及待执行的指令和数据;在
指令寄存器、
堆栈、状态字寄存器等中的内容。
(3)记账信息
(4)进程状态:进程当前所处的状态(后面讲)
4. I/O相关信息:文件描述符表
5. 信号相关信息
四、查看进程
前言:可执行程序存在于磁盘,在被执行时加载到内存(相当于一份同样的代码存在于两个不同的地方);同一个可执行程序可以被执行多次,生成多个进程;删除可执行程序,并不影响进程(仅仅删除的是磁盘上的可执行程序);所以可执行程序并不是进程。
1. 可以再/proc目录下查看进程 ls /proc xxxx
2. ps aux 查看所有进程相关信息
五、获取进程标识符
所有的进程都是由它的父进程创建,所以所有的进程都有一个共同的祖先;当操作系统启动时,会创建第一个进程叫做init进程
它的进程id = 1,以后所有的进程都是由他直接或间接创建;
(1)父进程id parent process id (ppid)
(2)进程id process id (pid)
可以通过函数 getpid()和getppid()函数查看他们的进程和父进程的id
函数原型:
#include
#include
pid_t getpid(void); //pid_t就是int
pid_t getppid(void);
#include
#include
int main()
{
//bootprintf("helllo world
");
printf("pid:%d
",getpid());
printf("ppid:%d
",getppid());
return 0;
}
六、通过系统调用函数fork()创建子进程
1. fork有两个返回值:父进程返回子进程pid,子进程返回0,如果失败返回-1
失败原因:(1)内存不够(2)同一父进程的子进程有上限
2. 父进程创建子进程的过程,是以父进程为模板,把父进程的PCB复制稍加修改(pid/ppid不同)内存指针基本相同,上下文也相同(EIP),父子进程执行同一份代码,申请结点内存,插入到链表中。又因为EIP相同,fork之后,父子进程都要从fork位置继续执行下去。fork之后父子进程执行先后顺序不确定,取决于操作系统的调度器的具体实现。
#include
#include
int main()
{
int ret = fork();
printf("pid = %d ret = %d
",getpid(),ret);
//printf("ppid:%d
",getppid());
//printf("pid:%d
",getpid());
sleep(1);
return 0;
}
fork需要if语句进行分流,不然特别混乱
#include
#include
int main()
{
int ret = fork();
if(ret>0)
{
//parent
printf("i am parent pid :%d ret = %d
",getpid(),ret);
}else if(ret == 0)
{
//child
printf("i am child pid :%d ret = %d
",getpid(),ret);
}else
{
perror("fork");
}
sleep(1);
return 0;
}