程序
:是完成特定任务的一系列指令集合
进程
从用户角度看,进程是程序的一次动态的执行过程
从内核角度看,进程是分配CPU,内存等系统资源的基本单位。每一个进程都有自己独立的地址空间和运行状态
进程是系统分配资源的最小单位
进程是程序的一次动态执行过程,需要对进程的现场信息进行维护,就需要相应的数据结构,对应的C语言的结构体,这个结构体叫PCB(process Control Block)
PCB是操作系统感知进程存在的数据构
进程和程序的区别:
程序是永久的,进程相对短暂
程序是静态的,进程是动态的
进程有PCB,程序没有
一个进程只能对应一个程序
一个程序可以对应多个进程
我们来看一个简单的进程,用getpid() 函数查看自己的ID
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{
printf("pid = %d\n",getpid()); //打印自己的pid
printf("ppidi= %d\n",getppid());//打印父亲的pid
return 0
}
我们可以看到,一个主函数是另一个进程的子进程。那么我们是否可以直接创建父进程和子进程?
fork() 该函数可以创建子进程。
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<unistd.h>
4 #include<sys/types.h>
5
6 int main()
7 {
8 int ret = 0;
9 ret = fork();
10 if(ret > 0) //fork返回值,大于0 进入父进程
11 {
12 printf("father\n");
13 printf("pid = %d\n",getpid());
14 }
15 else if(ret == 0) //fork返回值等于0 执行子进程
16 {
17 printf("child\n");
18 printf("pid = %d\n",getpid());
19 }
20 else //fork返回值小于0 fork失败
21 {
22 perror("fork\n");
23 return 1;
24 }
25 printf("finish\n");
26 return 0;
27 }
代码执行出的结果,子进程的ppid就是我们的父进程的pid。fork()后,子进程对于父进程是 写时拷贝.
写时拷贝
进程创建的一般过程
1.给新进程分配一个标识符。在内核中分配一PCB
2.复制父进程的环境
3.分配资源(地址空间,程序,数据,堆栈等)
4.复制父进程的地址空间的内容
5.将进程置成就绪状态,放入就绪队列
pid_t fork(void) 用来创建一个新进程
返回值:失败:-1
成功:父进程返回子进程ID,子进程返回0
子进程继承父进程那些东西?
地址空间
进程上下文(运行状态的信息)
进程堆栈
内存信息
文件描述符
信号设置
进程调度优先级
当前路径
根路径
进程组
资源限制
子进程不继承那些父进程的东西?
父进程的锁
父进程ID
父进程未决的信号子进程清除
进程在内核中的七中状态: