注意小点:
- 使用printf("%p",&a);打印出来的地址是相对地址,他其实不是一个地址,只是变量相距进程首地址的偏移量
- 在ubantu中父进程控制终端,终端也会优先响应父进程
- PID是该进程的进程号,PPID是父进程的进程号
1,程序
程序是数据和指令的集合(程序 = 数据结构+算法),一个程序的执行过程就是一个计算。
- 数据:用来表示人们思维对象的抽象概念的物理表现叫做数据。
- 指令:数据处理的规则叫做指令。
- 计算:对某一有限数据的集合所实施的、目的在于解决某一个问题的一组有限的操作(指令)的集合,称为一个计算(computation)。
计算机(computer)就是用指令来处理数据的机器。
2,程序的执行方式
(1) 顺序执行。
一条指令运行完,紧接着运行下一条指令。
缺点: CPU利用率太低。有时候指令需要去访问某个硬件,如果该硬件是忙碌状态需要等待。
(2) 并发执行(为了提高CPU的利用率)
现代操作系统为了程序能实现并发执行,特地的引入"进程"的概念。
3,进程的概念
什么是进程?
进程是具有独立功能的程序关于某个数据集合上的一次运行活动。(程序的一次执行)
4,程序和进程的区别
(1)程序是静态的概念(是指令的有序集合);进程是动态的概念(动态的产生和消亡),进程是程序的一次运行活动。
(2)进程是一个独立运行的活动单位;进程是总系统资源分配的基本单位。
(3)一个程序可以对应多个进程。但是一个进程只对应一个程序。
5,进程的状态和时间片轮转算法
执行状态: CPU正在运行这个进程的指令,该进程就是执行状态。执行状态会消耗时间片,时间片用完了就变成就绪状态。
就绪状态: 时候准备着可以运行的状态。
阻塞状态: 由于某种原因无法继续执行了,就会从执行状态变成阻塞状态。
在阻塞队列中的进程可以被信号唤醒,恢复到就绪状态。
6,Linux进程地址空间布局
在进程运行过程中,所需要的内存布局,在Linux操作系统对进程需要的内存进行分段(分类)管理,
不同属性的内存需要,分在不同的内存区域段。
gcc -c hello.c -o hello.o
- size hello.o 查看该可执行文件的内存分段的大小
- objdump -h hello.o 查看该可执行文件的内存分段的地址区间
./hello
cat /proc/$pid/maps 查看进程的虚拟地址的分配
7,前台进程和后台进程
(1)前台进程就是跟用户进行交互的进程,会占用终端。同理,后台程序不会占用终端的进程。
(2)前台进程来实现大部分的功能和占用大量的资源,后台进程一般用来实现对前台进程的一个维护的作用,占用少量资源。
(1)
①孤儿进程: 父进程已经退出的子进程,称为孤儿进程。孤儿进程由init进程(1号进程)托管回收资源。
②僵尸进程: 子进程已退出,但是其父进程没有调用wait/waitpid进行回收资源的子进程。
用 ps -ef 命令可查看 有 defunct 标识
③ 守护进程: 后台执行用来管理维护的进程。
(2)进程组
父子进程默认为同一进程组。
pid_t getpgrp(void);//用来获取自身的组ID号
int setpgid(pid_t pid, pit_t pgid);//用来把pid这个进程的组ID设置为pgid。
//注意,这里的pid和pgid只能是自身的PID或者是你的子进程的PID。
(3)会话: 前台进程组和后台进程组的联系,是多个进程组的集合。
如何实现后台运行呢?
- a. 创建一个子进程,然后把父进程退出子进程不退出。则该子进程就变成了后台进程。
- b. ./tftp_server & 后台运行,但是依赖于终端(终端关闭进程结束)
- c. nohup ./tftp_server & 后台运行,不依赖终端