做网站可以赚钱么,中国八大设计院指的是哪些,wordpress和typecho,杭州家装设计公司排名榜#x1f3e0;关于专栏#xff1a;Linux的浅学到熟知专栏用于记录Linux系统编程、网络编程等内容。 #x1f3af;每天努力一点点#xff0c;技术变化看得见 文章目录 冯诺依曼体系结构操作系统如何理解管理操作系统概念设计操作系统目的系统调用和库函数概念 进程基本概念描… 关于专栏Linux的浅学到熟知专栏用于记录Linux系统编程、网络编程等内容。 每天努力一点点技术变化看得见 文章目录 冯诺依曼体系结构操作系统如何理解管理操作系统概念设计操作系统目的系统调用和库函数概念 进程基本概念描述进程-PCB组织进程查看进程通过系统调用获取进程标识符通过系统调用创建进程 冯诺依曼体系结构
我们常见的计算机像我们日常使用的笔记本、台式机我们不常见的计算机如服务器大部分都遵循冯诺依曼体系结构。
在讨论冯诺依曼体系结构前我们先来了解一下该结构涉及的5个部分输入设备、输出设备、存储器、运算器、控制器。下面给出了这5个组件的举例
组件名称举例输入设备键盘、摄像头、话筒、磁盘、网卡…输出设备显示器、音响、磁盘、网卡…存储器内存…运算器算术运算单元、逻辑运算单元…控制器无举例负责协调外部就绪事件如将数据拷贝到内存等
下图描述的就是冯诺依曼体系结构其中外部设备输入、输出设备在进行数据交互时都是直接与存储器直接交互。而CPU从存储器直接获取数据或存储数据。在程序需要访问外部设备时CPU才会与外部设备有间接交互。 为什么CPU不直接与外部设备直接交互呢大家可能知道木桶效应整个木桶的盛水量取决于最低的那块木板。在计算机体系结构中也是这样的。
CPU具有非常快的计算速度而外部设备的速度太慢了。如果CPU直接与外部设备交互则CPU在需要获取或输出设备时均要等待外部设备整机效率取决于外部设备的处理速度。 如果我们让外部设备与存储器直接交互让CPU与存储器直接交互。在CPU进行计算时存储器可以与多个输入设备交互当CPU需要数据时直接从内存中获取即可如果CPU需要写入数据则将数据给存储器再由存储器与输出设备交互即可。这样一来整机的效率就取决于存储器的处理速度。大大提高了计算机的处理效率。
因此我们可以得出如下结论↓↓↓
CPU读取数据数据代码都是从内存中读取。站在数据的角度CPU不和外设直接交互CPU要处理数据需要将外设中的数据加载到内存。站在数据的角度外设直接只和内存打交道
★ps在冯诺依曼体系结构中当某个进程需要访问外设时CPU并不会一直等待外设而是使用中断的方式将其从CPU上换下来由其他进程执行。该程序到对应外设上等待外设处理完成后再向CPU的控制器发送中断信号表明自己已经处理完成可以回到CPU上运行。再由控制器来相应的信号、外部事件等。
★ps计算机中的寄存器的存取效率比磁盘等存储设备速度快为什么不将整机的存储设备均换成寄存器材质呢 一方面寄存器、内存设备掉电易失没电就没办法存储数据而磁盘、磁带等设备为磁性存储介质可以在没电的情况下继续保存出局另一方面寄存器、内存价格昂贵我们当前的计算机普遍是8G左右内存计算机的价格就已经较为昂贵了如果计算机将几百G的磁盘换成内存则一台计算机的价格将比现在的计算机贵上百倍。
★ps什么叫做IO从外部设备将数据拷贝到内存就是Input从内存将数据拷贝到外部设备就是Output这就是IO。
★ps为什么程序要运行必须先将程序加载到内存这其实就是冯诺依曼体系结构决定的。硬件设备为了提高整机效率规定了CPU只能从内存读取数据及指令。因此软件执行必须遵守硬件规定必须将待执行程序加载到内存。
【举例说明】如果在厦门要给远在哈尔滨的朋友发送一条消息。
此时我需要使用使用键盘外部设备打字键盘数据被写入存储器中CPU从存储器中获取键盘数据确定要怎么传输之后将CPU处理后的数据放到存储器中再由存储器将该数据传给网卡我的网卡与对方的网卡交互之后对方网卡将获取的数据写入存储器对方存储器再将数据传给CPUCPU对传来的数据进行解码等操作再将解码后的数据存入存储器由存储器负责将数据传给显示器进行显示。
★关于冯诺依曼体系结构需要强调以下几点
这里的存储器指的就是内存不考虑缓存的情况这里的CPU能且只能对内存进行读写不能访问外设输入、输出设备外设输入、输出设备要输入或输出数据只能写入内存或从内存中读取在冯诺依曼体系中所有设备只能和内存打交道以存储器为中心
操作系统
如何理解管理
例子1学校管理 大学里校长是怎么管理成千上午的学生的呢我们知道大学里面有辅导员、班长。他们协助校长管理学生校长不直接与学生打交道而是通过辅导员和班长来管理学生。
管理学生的本质是对学生数据做管理也就是对学生的学号、姓名、成绩等等信息做管理。因而我们可以使用一个结构体来定义一个学生类型再使用顺序表或者链表来组织学生信息。这种思想叫做“先描述再组织”。当校长发现某个数据有问题时他并不是直接找到这个学生而是让辅导员处理这个数据问题。
从这可知管理者和被管理者可以不执行交互沟通拿到被管理者的核心数据用于进行管理决策才是最重要的。 知识点操作系统如何管理外设 在计算机有个大boss——操作系统它不直接与外部设备打交道而是通过驱动程序管理外部设备。操作系统实际管理的就是一组外设的结构体数据的管理即对数据进行增删查改。 例子2银行提供服务 生活中我们需要到银行存取钱的时候都需要到柜台窗口办理业务再由业务人员与内部金库做交互。为什么不能让用户直接进入金库呢因为银行无法甄别哪些人是坏人。为了管理方便直接拒绝用户进入金库而提供了柜台这种形式的服务。这种方式不仅能给用户提供服务还保证了银行的安全。
知识点操作系统提供接口式服务 操作系统与银行类似它既要给用户提供服务但又担心用户的非法操作。因此操作系统提供了一个又一个的接口函数这样既能给用户提供服务又能保证操作系统的安全。
★psLinux是使用C语言实现的因此Linux的系统调用本质就是使用C语言实现的函数。
银行的组织结构与操作系统相似。行长借助安保、保洁、技术员等管理了银行里的各项资源而操作系统借助驱动程序管理计算机上的各项资源软硬件资源。为了给用户提供服务他们都使用了接口式服务但这种接口式服务对于某些用户来说仍然使用不便。因而银行就有了协助老年用户的引导员而操作系统就有了图形化界面、shell外壳、第三方库来为用户提供便捷的服务。此外操作系统上还有各种使用第三方库、系统调用等实现的应用程序如抖音、淘宝等为用户提供更加便捷的服务。 操作系统概念
任何计算机系统都包含一个基本的程序集合称为操作系统OS。它给用户提供了一个稳定、安全、简单的执行环境。
笼统的理解操作系统包括①内核进程管理、内存管理、文件管理、驱动管理②其他程序例如库函数、shell程序等
在整个计算机软硬件架构中操作系统的定位是一款纯正的“搞管理”的软件
设计操作系统目的
与硬件交互管理所有的软硬件资源为用户程序应用程序提供一个良好的执行环境
下图是操作系统在整个计算机体系中起着承上启下的作用。操作系统对下通过驱动程序管理各种硬件对上为用户提供各种系统接口对各个软件进行管理。 ★ps计算机管理硬件①描述起来用struct结构体 ②组织起来用链表或其他高效的数据结构
系统调用和库函数概念
在开发角度操作系统对外会表现为一个整体但是会暴露自己的部分接口供上层开发使用这部分由操作系统提供的接口叫做系统调用。
系统调用在使用上功能比较基础对用户的要求相对也比较高所以有心的开发者可以对部分系统调用进行适度封装从而形成库有了库就很有利于更上层用户或者开发者进行二次开发。
进程
其实我们启动一个软件本质就是启动一个进程。在Linux系统上运行一条命令如ls -al其实就是在系统层面创建了一个进程。因而我们可以得到如下概念↓↓↓
基本概念 ●课本概念程序的一个执行实例正在执行的程序等。 ●内核观点担当分配系统资源CPU时间、内存的实体。 Linux是可以同时加载多个程序的也就是说Linux是可以在系统中同时存在大量的进程的。那么Linux系统就必须对这些进程进行管理。Linux系统是如何管理大量的进程的呢答案是先描述再组织。
对于进程来说它包含各种属性数据因此需要一个结构来存储它即PCB进程控制块。
计算机中存在大量的可执行文件我们双击可执行文件后本质是将可执行文件从磁盘加载到内存中该可执行文件中包含了程序的代码和数据。但操作系统中有大量运行的程序为了管理好这些程序需要使用PCB结构体将各个运行的程序进程的属性数据进行保存。这样操作系统才知道该进程已经运行到哪一行是否已经执行结束等。
★ps在操作系统中会维护一个运行队列run_queue该队列上链接着等待CPU资源的进程的PCB。当CPU空闲时则会从run_queue中选择一个进程到CPU中执行这就是进程调度。 由此我们可以知道进程对应的代码和数据进程对应的PCB结构体
描述进程-PCB ●进程信息被放在一个叫做进程控制块的数据结构中可以理解为进程属性的集合。 ●课本上将其称之为PCBLinux操作系统下的PCB就是task_struct。 在Linux中描述进程的结构体叫做task_struct。task_struct是Linux内核的一种数据结构它会被装载到内存里并且包含着进程的信息。下表是对task_struct中存储内容的分类↓↓↓
存储项概述具体描述标识符描述进程的唯一标识符用来区别其他进程状态任务状态、退出代码、退出信号等优先级相对于其他进程的优先级程序计数器程序中即将被执行的下一条指令的地址内存指针包括程序代码和进程相关数据的指针还有和其他程序共享的内存块的指针上下文数据进程执行时处理器的寄存器中的数据I/O状态信息包括显示的I/O请求分配给进程的I/O设备和被进程使用的文件列表记账信息可能包括处理器时间总和使用的时钟数总和时间限制记账号等其他信息——
针对于上表中的上下文数据这里给出一个生活示例进行说明
大学生参军复学例子 大学里有不少同学会选择参军如果小明他大二上学期打算参军。此时他可以直接去参军不和学校内的学生信息管理机构上报吗如果小明他直接参军而没有在校报备等他1年后回来由于他全科挂科、旷课被开除了他就需要从大一重新开始读。
显然小明去参军是需要和学校报备的此时学生信息管理机构会将小明的信息存储起来。小明参完军是不是应该跟学校再报备一次并将学生信息恢复为正常在读状态呢那是当然。
这里的上下文就等同于小明的在校的信息上到大二年级等同于程序执行到第2行代码像这种离开时将自己的信息保存封存下来回来后再将信息恢复这样的操作称为上下文切换上下文保存及上下文恢复。当小明回到学校继续读大二年纪而不是从大一重新开始读就等同于程序回到CPU不是从头运行而是从上次运行停止处继续向下运行。
组织进程
进程结构可以在内核代码中找到它所有运行在Linux操作系统里的进程都以task_struct链表的形式存储在内核内。
查看进程
进程的信息可以通过/proc系统文件夹查看。我们通过ls命令可以看到/proc目录下有许多带数字的文件夹这些数字就是进程id用于唯一标识一个进程。 如要获取id为26126的进程信息我们只需要进入名为26126的目录中查看即可。使用ls -al查看目录内的详细内容这些都是该进程的相关信息其中cwd是当前进程的工作目录exe是当前进程对应的可执行文件的存储位置。如果创建了一个新的进程则会在/etc目录下创建一个名称与该进程pid相同的目录目录中保存该进程的相关属性、数据及代码若终止该进程则对应的目录会被操作系统自动删除。 还可以使用top命令查看进程的相关信息其中PID就是进程号进程id。 除了上述两种方法我们还可以使用ps命令配合选项查看进程的相关信息。↓↓↓ 示例演示 下面我们编写如下代码并将它编译运行可执行文件名为test。
#include stdio.h
#include unistd.hint main()
{while(1){sleep(1);}return 0;
}执行./test程序后我们再执行ps axj | head - 1 ps axj | grep test可以查看到执行该程序的进程信息↓↓↓ ★ps如果想终止当前在执行的程序可以使用ctrlC或使用kill -9 [进程id]来结束对应程序。
通过系统调用获取进程标识符
我们可以调用getpid获取当前进程的标识符进程id调用getppid获取当前进程的父进程的标识符父进程id。在使用该接口时需要包含sys/types和unistd两个头文件。 下面代码为getpid及getppid的使用示例运行结果在代码下方↓↓↓
#include stdio.h
#include unistd.h
#include sys/types.hint main()
{while(1){printf(my pid is %d\n, getpid());printf(my parents id is %d\n, getppid());sleep(1);}return 0;
}我们可以使用ps命令来验证一下上面的pid和ppid是否是当前进程和它的父进程的id↓↓↓ getpid可以获得当前进程的pidgetppid确实可以获得当前进程的父进程。但当前的父进程是哪个程序呢我们使用ps -p [进程pid]获取来获取对应pid的进程信息我们可以发现该进程的父进程是bash。 为什么父进程是bash呢bash就是当前与我们进行交互的命令行为了防止bash执行时该程序崩溃退出导致整个命令行无法使用。bash会创建子进程让该子进程执行该程序即使子进程崩溃退出也不会影响bash。
通过系统调用创建进程
可以使用fork创建进程。如果创建进程成功则会给父进程返回子进程id给子进程返回0如果创建失败则会给父进程返回-1。 下面代码演示了如何创建子进程程序执行结果如代码下方图片所示↓↓↓
#include stdio.h
#include stdlib.h
#include sys/types.h
#include unistd.hint main()
{pid_t id fork();if(id 0)//创建子进程失败{perror(fork);exit(1);}else if(id 0)//子进程执行{printf(I am child process, my pid is %d, my ppid is %d\n, getpid(), getppid());exit(0);}else//父进程执行{printf(I am parent process, my pid is %d\n, getpid());}return 0;
}父、子进程是代码共享的但由于fork之后父子进程获得id值不同因此子进程执行id 0的分支而父进程执行的是else分支。
创建子进程本质上操作系统上就多了一个新的进程因此操作系统需要给子进程分配一个PCB结构体并给它一个唯一的p进程id。
★ps为什么给子进程返回0给父进程返回子进程的pid父进程:子进程1:n父进程有多个子进程为了方便子进程管理、标识指定的子进程需要让fork给父进程返回子进程的pid当父进程能区分不同的子进程。 欢迎进入从浅学到熟知Linux专栏查看更多文章。 如果上述内容有任何问题欢迎在下方留言区指正b(▽)d