资源预览内容
第1页 / 共25页
第2页 / 共25页
第3页 / 共25页
第4页 / 共25页
第5页 / 共25页
第6页 / 共25页
第7页 / 共25页
第8页 / 共25页
第9页 / 共25页
第10页 / 共25页
亲,该文档总共25页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
1、线程与进程的区别进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。一个线程包含以下内容:一个指向当前被执行指令的指令指针;一个栈;一个寄存器值的集合,定义了一部分描述正在执行线程的处理器状态的值;一个私有的数据区。竞态条件竞态条件指的是一种特殊的情况,在这种情况下各个执行单元以一种没有逻辑的顺序执行动作,从而导致意想不到的结果。举一个例子,线程 T 修改资源 R 后,释放了它对 R 的写访问权,之后又重新夺回 R 的读访问权再使用它,并以为它的状态仍然保持在它释放它之后的状态。但是在写访问权释放后到重新夺回读访问权的这段时间间隔中,可能另一个线程已经修改了 R 的状态。另一个经典的竞态条件的例子就是生产者/消费者模型。生产者通常使用同一个物理内存空间保存被生产的信息。一般说来,我们不会忘记在生产者与消费者的并发访问之间保护这个空间。容易被我们忘记的是生产者必须确保在生产新信息前,旧的信息已被消费者所读取。如果我们没有采取相应的预防措施,我们将面临生产的信息从未被消费的危险。如果静态条件没有被妥善的管理,将导致安全系统的漏洞。同一个应用程序的另一个实例很可能会引发一系列开发者所预计不到的事件。一般来说,必须对那种用于确认身份鉴别结果的布尔量的写访问做最完善的保护。如果没有这么做,那么在它的状态被身份鉴别机制设置后,到它被读取以保护对资源的访问的这段时间内,很有可能已经被修改了。已知的安全漏洞很多都归咎于对静态条件不恰当的管理。其中之一甚至影响了 Unix 操作系统的内核。死锁指的是由于两个或多个执行单元之间相互等待对方结束而引起阻塞的情况。例如:一个线程 T1 获得了对资源 R1 的访问权。一个线程 T2 获得了对资源 R2 的访问权。T1 请求对 R2 的访问权但是由于此权力被 T2 所占而不得不等待。T2 请求对 R1 的访问权但是由于此权力被 T1 所占而不得不等待。T1 和 T2 将永远维持等待状态,此时我们陷入了死锁的处境!针对此问题主要有三种解决方案:1)在同一时刻不允许一个线程访问多个资源。2)为资源访问权的获取定义一个关系顺序。换句话说,当一个线程已经获得了 R1 的访问权后,将无法获得 R2 的访问权。当然,访问权的释放必须遵循相反的顺序。3)为所有访问资源的请求系统地定义一个最大等待时间(超时时间) ,并妥善处理请求失败的情况。几乎所有的.NET 的同步机制都提供了这个功能。前两种技术效率更高但是也更加难于实现。事实上,它们都需要很强的约束,而这点随着应用程序的演变将越来越难以维护。尽管如此,使用这些技术不会存在失败的情况。大的项目通常使用第三种方法。事实上,如果项目很大,一般来说它会使用大量的资源。在这种情况下,资源之间发生冲突的概率很低,也就意味着失败的情况会比较罕见。我们认为这是一种乐观的方法。秉着同样的精神,我们在 19.5 节描述了一种乐观的数据库访问模型。2、 new 和 malloc 的区别A)malloc 与 free 是 C+/C 语言的标准库函数,new/delete 是 C+的运算符。它们都可用于申请动态内存和释放内存。 B)对于非内部数据类型的对象而言,光用 malloc/free 无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于 malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于 malloc/free。 C)因此 C+语言需要一个能完成动态内存分配和初始化工作 的运算符 new,以一个能完成清理与释放内存工作的运算符 delete。注意 new/delete 不是库函数。 D)C+ 程序经常要调用 C 函数,而 C 程序只能用 malloc/free 管理动态内存 new 是个操作符,和什么+,-,=.有一样的地位. malloc 是个分配内存的函数,供你调用的. new 是保留字, 不需要头文件支持. malloc 需要头文件库函数支持 . new 建立的是一个对象,malloc 分配的是一块内存. free()到底释放了什么简而言之: new 是一个操作符,可以重载 malloc 是一个函数,可以覆盖 new 初始化对象,调用对象的构造函数,对应的 delete 调用相应的析构函数 malloc 仅仅分配内存,free 仅仅回收内存 这个问题比较简单,其实我是想和第二大部分的题目相呼应而已!哈哈!free()释放的是指针指向的内存!注意!释放的是内存,不是指针!这点非常非常重要!指针是一个变量,只有程序结束时才被销毁。释放了内存空间后,原来指向这块空间的指针还是存在!只不过现在指针指向的内容的垃圾,是未定义的,所以说是垃圾。因此,前面我已经说过了,释放内存后把指针指向 NULL,防止指针在后面不小心又被解引用了。非常重要啊这一点 new 建立的对象你可以把它当成一个普通的对象, 用成员函数访问,不要直接访问它的地址空间 malloc 分配的是一块内存区域,就用指针访问好了,而且还可以在里面移动指针 . 在进行 C/C+编程开发时,经常会遇到 malloc/free 与 new/delete 这两对操作,主要功能就是可以在程序运行过程中动态的申请、释放内存,从而达到对内存的操作。但是这两对操作是有区别的,不能交叉搭配使用:即不能 free 掉 new 来的内存,也不能 delete 掉malloc 来的内存空间。虽然有时候可以 delete 掉 malloc 来的内存,或者 free 掉 new 来的内存,但是通常情况下会给程序带来不可预知的错误,相信这不是编程人员所希望看到的。要养成一个良好的习惯就是严格的配对使用:只用 free 来释放 malloc 的内存空间、只用delete 来释放 new 来的内存空间。 这两对操作的区别: 1、 malloc/free 是 C/C+中的方法(函数) ,new/delete 是 C+中的操作符。 2、 malloc 申请的是 heap 区的内存空间,而 new 则是申请的 free store 区的内存空间。3、使用 free 之前要判断,使其 free 的指针是!NULL 的,使用 delete 则无须判断。 4、free 掉的内存是该指针指向的一段内存空间,里面应该是空的。而 delete 掉的内存是里面确实存有数据或者对象的。 5、一下举例说明其区别: malloc 和 free(及其变体) 会产生问题的原因在于它们太简单:他们不知道构造函数和析构函数。 假设用两种方法给一个包含 10 个 string 对象的数组分配空间,一个用 malloc,另一个用new: string *stringarray1 = static_cast(malloc(10 * sizeof(string); string *stringarray2 = new string10; 其结果是,stringarray1 确实指向的是可以容纳 10 个 string 对象的足够空间,但内存里并没有创建这些对象。而且,如果你不从这种晦涩的语法怪圈里跳出来的话,你没有办法来初始化数组里的对象。换句话说,stringarray1 其实一点用也没有。相反,stringarray2 指向的是一个包含 10 个完全构造好的 string 对象的数组, 每个对象可以在任何读取 string 的操作里安全使用。 假设你想了个怪招对 stringarray1 数组里的对象进行了初始化,那么在你后面的程序里你一定会这么做: free(stringarray1); delete stringarray2;/ 参见条款 5:这里为什么要加上个 调用 free 将会释放 stringarray1 指向的内存,但内存里的 string 对象不会调用析构函数。如果 string 对象象一般情况那样,自己已经分配了内存,那这些内存将会全部丢失。相反,当对 stringarray2 调用 delete 时,数组里的每个对象都会在内存释放前调用析构函数。 既然 new 和 delete 可以这么有效地与构造函数和析构函数交互,选用它们是显然的。把 new 和 delete 与 malloc 和 free 混在一起用也是个坏想法。对一个用 new 获取来的指针调用 free,或者对一个用 malloc 获取来的指针调用 delete,其后果是不可预测的。大家都知道“不可预测”的意思:它可能在开发阶段工作良好,在测试阶段工作良好,但也可能会最后在你最重要的客户的脸上爆炸。 new/delete 和 malloc/free 的不兼容性常常会导致一些严重的复杂性问题。举个例子,里通常有个 strdup 函数,它得到一个 char*字符串然后返回其拷贝: char * strdup(const char *ps); / 返回 ps 所指的拷贝 在有些地方,c 和 c+用的是同一个 strdup 版本,所以函数内部是用 malloc 分配内存。这样的话,一些不知情的 c+程序员会在调用 strdup 后忽视了必须对 strdup 返回的指针进行 free 操作。为了防止这一情况,有些地方会专门为 c+重写 strdup,并在函数内部调用了 new,这就要求其调用者记得最后用 delete。你可以想象,这会导致多么严重的移植性问题,因为代码中 strdup 以不同的形式在不同的地方之间颠来倒去。 c+程序员和 c 程序员一样对代码重用十分感兴趣。大家都知道,有大量基于 malloc和 free 写成的代码构成的 c 库都非常值得重用。在利用这些库时,最好是你不用负责去free 掉由库自己 malloc 的内存,并且/或者,你不用去 malloc 库自己会 free 掉的内存,这样就太好了。其实,在 c+程序里使用 malloc 和 free 没有错,只要保证用 malloc 得到的指针用 free,或者用 new 得到的指针最后用 delete 来操作就可以了。千万别马虎地把 new和 free 或 malloc 和 delete 混起来用,那只会自找麻烦。 既然 malloc 和 free 对构造函数和析构函数一无所知,把 malloc/free 和 new/delete 混起来用又像嘈杂拥挤的晚会那样难以控制,那么,你最好就什么时候都一心一意地使用new 和 delete 吧3、栈空间和堆空间 一个由 C/C+编译的程序占用的内存分为以下几个部分:1、 栈区(stack ):又编译器自动分配释放,存放函数的参数值,局部变量的值等,其操作方式类似于数据结构的栈。2、 堆区(heap):一般是由程序员分配释放,若程序员不释放的话,程序结束时可能由 OS 回收,值得注意的是他与数据结构的堆是两回事,分配方式倒是类似于数据结构的链表。3、 全局区(static ):也叫静态数据内存空间,存储 全局变量 和静态变量,全局变量和静态变量的存储是放一块的,初始化的全局变量和静态变量放一块区域,没有初始化的在相邻的另一块区域,程序结束后由系统释放。4、 文字常量区:常量字符串就是放在这里,程序结束后由系统释放。5、 程序代码区:存放函数体的二进制代码。堆和栈的区别:一、由以上综述就可以得知,他们程序的内存分配方式不同。二、申请和响
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号