输入设备:键盘、鼠标、网卡、显卡等等
输出设备:显示器,打印机等等
中央处理器(CPU):运算器和控制器等
需要知道的是——冯.诺依曼体系结构是现代计算机的基础
现在大多计算机仍是冯.诺依曼计算机的组织结构,只是作了一些改进而已,并没有从根本上突破冯体系结构的束缚。
计算机是各种硬件构成的,那么这些硬件就需要软件去操控。
任何计算机系统都包含一个基本的程序集合,称为操作系统(OS)。笼统的理解,操作系统包括:
内核(进程管理,内存管理,文件管理,驱动管理)
其他程序(例如函数库,shell程序等等)
设计OS的目的
1.与硬件交互,管理所有的软硬件资源
2.为用户程序(应用程序)提供一个良好的执行环境
计算机软件和硬件之间的结构图如下:
课本概念:程序的一个执行实例,正在执行的程序等
内核观点:担当分配系统资源(CPU时间,内存)的实体
(包含着程序代码 + 相关数据结构)
首先,程序就是我们所写的代码也就是一堆文字符号,而真正想要运行,得要和计算机软件硬件联系起来。按照课本上的定义,被加载到内存中的程序就叫做进程。而这些进程都是由操作系统来管理的。比如去分配资源比如时间片等等去进行各种调度策略这里我们不做赘述想要了解的同学可以去查查资料。
我们知道进程是由操作系统管理的,它管理的方式就是先描述再组织。我们知道linux操作系统是由C语言编写的,那么描述进程的结构就用的是结构体。描述进程的结构体也叫做PCB。
标示符: 描述本进程的唯一标示符,用来区别其他进程。
状态: 任务状态,退出代码,退出信号等。
优先级: 相对于其他进程的优先级。
程序计数器: 程序中即将被执行的下一条指令的地址。
内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
上下文数据: 进程执行时处理器的寄存器中的数据[休学例子,要加图CPU,寄存器]。
I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
其他信息
小结:一个程序想要运行的时候就会以进程的形式存在,当进程生成的时候,OS会给进程自动创建一个对应的PCB来管理进程。曾经我们运行各种程序的本质就是在操作系统上建立进程!!!
上边说完了描述进程,接下来说说怎么组织进程。
进程的组织方式一共有三种:
如下图所示,在内存中多个进程都有自己的进程号id,一个进程是包含他的代码段和数据段以及相关的数据结构的。linux下task_struct中数据会保存对应进程数据和代码地址,而每一个进程之间也可以相互通信。
当CPU调度的时候,只需要提供给CPU ,PCB相关数据就会找到对应的进程去调度。
并且所有运行在系统里的进程都以task_struct链表的形式储存在内核里。
#include
#include
#include
int main()
{
printf("pid: %d\n", getpid());//打印该进程的id号
printf("ppid: %d\n", getppid());//打印该进程父进程的id号
return 0;
}
实践操作一下:
负值:创建子进程失败。
零:返回到新创建的子进程。
正值:返回父进程或调用者。该值包含新创建的子进程的进程ID
就是好比细胞分裂,父亲和孩子从fork();语句开始共享同一份代码和数据,并且都向下执行。(相当于两个程序一起跑)
当然一个父进程也可以有多个子进程
这里要注意fork函数有两个返回值,一个是父进程的返回值,返回子进程的id。二是子进程的返回值,正常返回0,错误返回一个负值。
调用fork之后,数据、堆、栈有两份,代码仍然为一份但是这个代码段成为两个进程的共享代码段都从fork函数中返回,箭头表示各自的执行处。当父子进程有一个想要修改数据或者堆栈时,两个进程真正分裂。
引用一位网友的话来解释fork函数返回的值为什么在父子进程中不同。“其实就相当于链表,进程形成了链表,父进程的fork函数返回的值指向子进程的进程id, 因为子进程没有子进程,所以其fork函数返回的值为0.
具体参见fork百度百科
举例如下,用if语句判断fork函数返回值不同区别父子进程,来执行不同代码,可以看到最后父进程返回值是子进程的ID,子进程返回0.
一个进程可以有几个状态(在linux内核下进程也可以叫任务)
static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};
本篇文章带你了解进程初识,了解进程已经父子进程的概念。