- 博客(26)
- 资源 (38)
- 收藏
- 关注
原创 操作系统-16-进程退出后占用的内存去哪了?
进程退出后占用的内存去哪了?作为程序员我们需要执行,当进程结束后,进程占用的所有的内存空间将被操作系统回收,包括函数调用使用的栈、动态内存分配使用的堆、代码段中的机器指令、数据段中的全局变量等。所谓回收,就是将进程所占用的内存空间标记为可用,可以用于其它用途了。而当进程运行时这些所占用的内存是不可以用作其它用途的。因此,我们不用担心堆区上动态分配的内存在程序结束前没有释放,这是不会造成内存泄漏的,因为进程退出后包括堆区在内所有占用的内存都会被操作系统回收,如图所示:因此如果程序存在内存泄漏但是又一时找
2021-04-23 23:04:49 1283
原创 操作系统-15-进程的创建
从这一节起,我们将详细讲解进程的一生。进程如人生,进程的一生同样包含三个阶段,创建,运行和终结,本节是进程三部曲的开篇:进程创建。接下来,我们讲解关于进程创建的诸多问题。进程是由谁创建的?在什么情况下创建的?幸好这个问题不像鸡生蛋蛋生鸡那样,这个问题的答案相对简单,进程的创建者有两种:1.操作系统可以创建新的进程2.进程也可以创建新的进程其中,进程的创建者被称为父进程,创建出的进程被称为子进程。1,操作系统创建进程:初始化作为计算机的Boss,最初的进程是由操作系统创建的,操作系统在初始化的
2021-04-14 12:12:21 11908 3
原创 操作系统-14-操作系统是如何运行的
操作系统是如何启动的我们已经知道了,操作系统其实就是一个大的C程序,本质上和我们自己写的C程序没什么区别,用户程序要想运行起来需要被操作系统从磁盘加载到内存中,那么操作系统是如何运行起来的呢?我们可以自己想一下这个问题,计算机在关机状态下也就是不通电的状态下内存是不能保存内容的,因此一般情况下操作系统和我们的程序一样都是保存在磁盘当中(没有磁盘的计算设备,例如嵌入式设备,会保存在ROM中,稍后会有解释),那么操作系统要想运行起来必然需要被什么东西加载到内存当中。当我们按下计算机的开机按键后,这时的计算
2021-04-11 22:25:52 3291 2
原创 链接器的理解-05-重定位
我们继续来讲解链接器的重定位。程序的运行过程就是CPU不断的从内存中取出指令然后执行执行的过程,对于函数调用来说比如我们在C/C++语言中调用简单的加法函数add,其对应的汇编指令可能是这样的:call 0x4004fd其中0x4004fd即为函数add在内存中的地址,当CPU执行这条语句的时候就会跳转到0x4004fd这个位置开始执行函数add对应的机器指令。再比如我们在C语言中对一个全局变量g_num不断加一来进行计数,其对应的汇编指令可能是这样的:mov 0x400fda %eaxadd
2021-04-11 16:24:56 979 1
原创 链接器的理解-04-库与可执行文件的生成<下>
我们继续来看动态链接。我们知道静态库在编译链接期间就被打包copy到了可执行文件,也就是说静态库其实是在编译期间(Compile time)链接使用的,那么动态库又是在什么时候才链接使用的呢,动态链接可以在两种情况下被链接使用,分别是load-time dynamic linking(加载时动态链接) 以及 run-time dynamic linking(运行时动态链接),接下来我们分别讲解一下。load-time dynamic linking(加载时动态链接)首先可能有的同学会问,什么是load
2021-04-11 12:59:44 254
原创 链接器的理解-03-库与可执行文件的生成<上>
在链接器可操作的元素这一节中我们提到,链接器可以操作的最小单元为目标文件,也就是说我们见到的无论是静态库、动态库、可执行文件,都是基于目标文件构建出来的。目标文件就好比乐高积木中最小的零部件。给定目标文件以及链接选项,链接器可以生成两种库,分别是静态库以及动态库,如图所示,给定同样的目标文件,链接器可以生成两种不同类型的库,接下来我们分别介绍。静态库假设这样一个应用场景,基础设计团队设计了好多实用并且功能强大的工具函数,业务团队需要用到里面的各种函数。每次新添加其中一个函数,业务团队都要去找相应的实
2021-04-10 16:31:09 349
原创 操作系统-13-程序员应如何理解中断
在这一节中我们聊一聊,操作系统管理外设的中断机制。为什么要在这一节聊一聊操作系统如何管理外设呢,外设管理是操作系统的核心任务之一,理解操作系统的外设管理机制对于我们理解操作系统工作原理至关重要。通过第二章的讲解,我们已经知道了,利用系统调用这种机制,我们可以向操作系统发起请求来创建进程、读写文件等等,虽然我们还没有讲解操作系统如何进行进程管理文件管理等,至少操作系统的这一部分工作机制,也就是系统调用,对于我们来说已经不再神秘了,但是我们依然不清楚操作系统是如何管理外部设备(鼠标、键盘、USB设备、打印机、
2021-04-09 00:04:46 632 5
原创 链接器的理解-02-符号决议
所有的应用程序都是链接器将所需要的一个个简单的目标文件汇集起来形成的。你可以将这个过程想象成拼图游戏,每个拼块就是一个简单的目标文件:1,拼图游戏当中的每个拼块都依赖于其它拼块提供的拼接口,这就好比我们写的程序模块依赖于其它模块提供的编程接口,比如我们在list.c中实现了一种特定的链表数据结构,其它模块需要使用这种链表,这就是模块间的依赖。而链接器其中一项任务就是要确保提供给链接器进行链接的目标文件集合之间依赖是成立的(也就是说,不会出现在被依赖的模块中链接器找不到需要的接口),这就是后面我们要讲到的符
2021-04-08 21:23:51 376
原创 链接器的理解-01-前言
对于C++源文件,从文本到可执行文件一般需要四个过程:预处理阶段:对源代码文件中文件包含关系(头文件)、预编译语句(宏定义)进行分析和替换,生成预编译文件。编译阶段:将经过预处理后的预编译文件转换成特定汇编代码,生成汇编文件汇编阶段:将编译阶段生成的汇编文件转化成机器码,生成可重定位目标文件链接阶段:将多个目标文件及所需要的库连接成最终的可执行目标文件在介绍本章的主题之前,我们先来看几个问题:问题一写C/C++的同学应该经常遇到这样的一个Error:“undefined reference
2021-04-08 09:50:49 225 3
原创 C 库函数 - atof()
1.包含头文件#include <stdlib.h>2.介绍:描述C 库函数 double atof(const char *str) 把参数 str 所指向的字符串转换为一个浮点数(类型为 double 型)。声明下面是 atof() 函数的声明。double atof(const char *str)参数str – 要转换为浮点数的字符串。返回值函数返回转换后的双精度浮点数,如果没有执行有效的转换,则返回零(0.0)。3.使用示例...
2021-04-07 15:23:58 292
原创 互斥锁的使用(CreateMutex等使用)
目录1.CreateMutex函数原型2.WaitForSingleObject的理解3.CreateMutex和WaitForSingleObject的配合使用3.1如何加锁3.2如何解锁4.使用示例5.注意1.CreateMutex函数原型HANDLE CreateMutex( LPSECURITY_ATTRIBUTES lpMutexAttributes, // 指向安全属性的指针 BOOL bInitialOwner, // 初始化互斥对象的所有者,如果希望进程立即拥有互斥体则设为FALSE
2021-04-07 14:17:34 3455 1
原创 操作系统-11-以发展的眼光来看待操作系统
操作系统和生物一样也是在不断演变进化的,操作系统也不是一下子就变成现在这种样子的。现代的操作系统是什么样子的呢?1.非常靓丽易用的图形界面2.普遍支持多任务,也就是操作系统上可以同时运行很多程序。3.所有进程看到的内存都是4G(32位下),而且无论物理内存是多少都是这样的。4.应用程序无需全部加载到内存中就可以开始运行。5.一个进程崩溃后不会影响到其它进程。6.等等等等在个人计算机(PC)刚刚出现时,所谓的操作系统在现在看来还非常原始,在这里我们以微软的 MS-DOS 为例来给大家讲解一下最
2021-04-06 20:41:47 159
原创 操作系统-10-程序员应如何理解系统调用<下>
系统调用类型由于一个系统的功能都是通过系统调用对外提供的,因此应用程序能够实现的最强大的功能不会超过系统调用提供给应用程序的能力。根据类型系统调用大体可以划分为以下几类:1.进程控制:一个运行中的进程可以创建另外一个进程去完成某项工作,这样当前进程就有机会去处理自己感兴趣的事情,这类系统调用在Linux中是fork(),在Windows下CreateProcess()。当我们创建新的进程后,可能需要等待其运行完成,这时我们需要的系统调用是Linux下的wait()或者Windows下的WaitForS
2021-04-06 14:01:21 248
原创 操作系统-09-程序员应如何理解系统调用<上>
操作系统主要有两项功能:1.向用户程序提供一个友好的编程接口,即系统调用2.管理计算机资源(包括CPU、内存、磁盘、网卡等外设,以及进程管理,线程管理,文件管理等)通常操作系统如何管理计算资源对于程序员来说是不可见的,应用程序想要使用系统资源必须通过操作系统,从这个角度讲操作系统更像是server,我们的应用程序是client,client只需要向server发出request然后得到response,至于server如何处理请求并不要client关心。同样的道理,应用程序只需要进行系统调用,而操作系
2021-04-05 22:51:50 485 4
原创 操作系统-08-系统调用是如何实现的
在上一节《操作系统如何看待进程》中,我们已经知道,操作系统对于用户程序是不信任的,因此操作系统需要对用户程序进行严加防范,那么操作系统该如何做到这一点呢,这就涉及到了“控制与被控制”的问题,在这里被控制的一方是用户程序,而施加控制的一方是操作系统,同时“控制与被控制”是单向的,用户程序不能翻过来控制操作系统。要做到这一点,我们首先来看一个例子你就明白啦。警察与囚犯,操作系统与进程我们知道囚犯被关在监牢里面,其活动范围只能局限在监牢这个狭小的范围内,如果囚犯试图越狱的话会触发监狱的警报,这时警察就会立即将
2021-04-05 20:40:55 460
原创 操作系统-07-操作系统是如何看待进程的
进程是操作系统中最重要的概念,没有之一,操作系统中大部分设计都是围绕“进程”这个概念实现的。因此能否彻底理解进程将直接影响程序员对于操作系统的理解。不简单的HelloWorld可能许多程序员都没有意识到我们的代码中有许多操作必须依赖操作系统才能完成,比如在网络通信程序中,从socket进行数据的读取与写入实际上是操作系统替我们完成的。由于操作系统对复杂的操作过程进行了封装,因此在程序员眼里这仅仅就是一个函数调用没什么大不了的。不过这也从设计的角度说明了操作系统的作用,那就是封装复杂的硬件操作过程,对外界
2021-04-04 19:11:06 235
原创 操作系统-06-程序员应如何理解CPU<下>
程序计数器(Program Counter)到目前为止,我们介绍了CPU的工作过程,这个过程非常简单,CPU从内存中取出指令,执行指令然后继续从内存中取出指令。。但是有个问题我们没有回答,那就是:CPU是怎么知道从内存中的哪个位置取出指令呢?原来,CPU中有一个专门的寄存器用来存放下一条指令的内存地址。当CPU执行完一个指令后,就会根据这个寄存器中的内存地址取出下一条指令,取出指令后,该寄存器的内存地址+1,然后指向CPU要执行的下一条指令。这个寄存器在大部分教材中叫做Program Counter
2021-04-04 17:46:05 244
原创 操作系统-05-程序员应如何理解CPU<上>
你可能会想,作为程序员,我们需要理解CPU吗?是的,如果你想彻底理解操作系统的话。在后面的课程中你会发现,仅仅依赖软件是无法完成某些特定的功能的,比如,我们在《程序员如何理解内存》这一节中提到的虚拟内存,这项功能的实现需要依赖CPU的配合才能完成。因此在这一节中,将重点讲解一下作为程序员应该知道哪些CPU相关的知识。什么是机器指令你肯定已经知道了,CPU是计算机的大脑,程序员写的代码最终都是CPU来执行的。但作为计算机的大脑,CPU并不认识C,C++、Python、Java等语言,这些语言是人类可以
2021-04-04 17:05:48 225
原创 操作系统-04-程序员如何理解内存<下>
堆与栈的本质是什么在编程语言中,堆区和栈区本质上都是内存,因此二者在本质上没有任何区别,只不过这两块内存的使用方式是不一样的。在数据结构与算法中,我们也有堆和栈的概念,但那里指的不是内存,而是两种数据结构。你可能会想,我们为什么要费尽心力的提出堆和栈这两个概念呢?之所以需要区分两种内存用法,根源在于:内存是有限的。如果计算机内存是无限的,那么我们根本就不用这么麻烦的给内存划分两个区域,在其中的一个区域中这样使用内存,另一区域那样使用内存,这些都是不需要的。即使在今天PC内存普遍都在8G、16G,这依
2021-04-03 15:12:51 262
原创 操作系统-03-程序员如何理解内存<上>
什么是内存0和1这两个简单的数字能做什么?在其它学科中也许什么都做不了,但是在计算机科学中这就是全部。精彩纷呈的计算机世界正是构筑在这样两个简单数字之上。内存本身其实非常简单,内存的作用就是用来装数字0和数字1的,如图所示,图中的一个盒子就是内存的一个基本单元,装的不是0就是装的1。内存由一大堆的“盒子”组成,每个盒子中要么是0要么是1,其中8个盒子被称之为一个“字节”,每8个盒子也就是一个字节都有一个编号,这些编号就是简单的从0开始依次累加的,这个编号就被称之为“内存地址”。如图所示,你可以把内存
2021-04-02 16:34:37 196
原创 操作系统-02-什么是程序,什么又是进程?
本节是操作系统系列教程的第二篇文章,属于操作系统第一章即基础篇,在真正开始操作系统相关章节前在这一部分回顾一些重要的主题,算是温故知新吧,以下是正文。到目前为止,你肯定已经见过很多次这两个词了,“程序”“进程”。那程序和进程到底有什么区别呢。程序是一个静态的概念。进程是一个动态的概念。我们用一个例子来形象的讲解一下这个区别。程序其实本质上和我们的菜谱非常类似,一个菜谱规定了完成一道菜的整个流程,一步一步每个节点执行什么样的操作,但是看一遍菜谱是不能变出一道美味可口的菜肴的。要想真正做出一道菜就应该按
2021-04-01 19:43:44 926
原创 操作系统-01-什么是程序?
本节是操作系统系列教程的第一篇文章,属于操作系统第一章即基础篇,在真正开始操作系统相关章节前在这一部分回顾一些重要的主题,算是温故知新吧,以下是正文。虽然在这里我们主要关注的是操作系统,但毕竟操作系统的目的就是能更好的运行用户程序,而且该教程主要是站在程序员的角度来讲解操作系统,作为程序员是绕不开程序这个话题的,因此在深入理解操作系统之前还是有必要来聊一聊程序是怎么一回事。究竟什么是程序?我们引用Wikipedia对计算机程序的定义:A computer program is a collectio
2021-04-01 19:22:38 723 2
原创 SafeArrayAccessData,SafeArrayUnaccessData使用
SafeArray是VB中的数组存储方式。通过SafeArray,可以在VC++和VB间相互调用。SafeArray也是Automation中的标准数组存储方式。1. SafeArrayAccessData函数原型:HRESULT SafeArrayAccessData( SAFEARRAY * psa, void HUGEP ** ppvData);这个函数用于获取SafeArray的数据指针,并锁定SafeArray数组的数据。
2021-04-01 14:22:37 1441
原创 MFC中之GetProfileInt,WriteProfileString的使用
1.简介CWinApp类中提供了一组用于读写应用程序配置的方法:GetProfileIntWriteProfileIntGetProfileStringWriteProfileString可方便的用于读写应用程序配置。2.关于CWinApp::SetRegistryKey方法用VC++的向导建立MFC项目之后,在InitInstance中可以看到这样的语句:SetRegistryKey(_T(“应用程序向导生成的本地应用程序”));该函数将为以上提到的几个方法建立工作环境,此时如果用
2021-04-01 09:59:39 2202
mysql+connetcot.txt
2019-12-29
30岁的程序员如何防脱
2023-10-16
TA创建的收藏夹 TA关注的收藏夹
TA关注的人