这段时间司在招实习生,而不管是远程的电话面试或者是实际现场面试中领导都喜欢问你这个问题,但是可惜的是能很好答上来的人很少。后来发现不管是应届的实习生,甚至有些实际参加工作几年的人也未必真的了解这个问题。今天想写一篇详解,希望对广大程序员有一定的帮助。

区别1:全局堆句柄不一样。

网上有一个说法,就是一个线程一个栈,一个模块一个堆。前者很容易有理解,每个线程创建的时候在CreateThread中都能制定默认栈大小,只是很多情况下都取了默认值。而一个模块一个堆呢?其实很简单测试,如果是一个多线程MT编译方式的程序,你写一个dll,导出一个函数,参数设置为vector<int>,然后在exe中调用,当导出函数结束时就会崩溃掉。其实原因很简单,就是因为初始化向量空间时malloc内存的过程在exe中,而vector析构时会free内存,申请和释放的模块不一致而违背了一个模块一个堆的说法。

细心者会发现,其实不管是new/delete还是malloc/free最终调用的都是HeapAlloc/HeapFree,而这个函数的第一个参数为一个全局的堆句柄,由CreateHeap创建,创建该全局堆句柄的尚且在main等系列主函数之前。事实上这种夸模块堆操作异常总结起来就是申请内存时HeapAlloc传入的句柄和释放该内存时HeapFree传入的句柄不一致引起的,读者可写代码测试。

但是以上问题如果是多线程MD编译方式下便可解决,也就是说如果都是通过多线程MD编译方式出来的程序,如果是A模块中申请的内存到B模块中释放不会出现问题。

区别2:链接的运行时库不同。

对于多线程MT的程序来说,其连接的是libcmt.lib,该文件属于C语言运行时库,整个lib都会连接到PE文件当中。而多线程MD的程序链接的却是类似msvcpXXX.dll,该文件属于微软运行时库.也就是说如果是多线程MD编译出来的文件运行时都会加载相应版本的运行时库,当如果找不到运行时库就会报错而无法运行,同时如果运行时库不匹配也会出现各种意料之外的崩溃或者程序根本跑不起来等情况。

区别3:编译出来的PE文件大小区别

此时如果两者作为对比就会很明显看到多线程MT编译出来的文件体积要比多线程MD编译出来的大,因为MT是把对应的运行时库直接放到编译出来的PE文件当中,而MD却是运行的时候从第三方dll中获取运行时库,自己本身却不包含。同时另外的区别也很明显,多线程MT编译出来的文件运行时不需要加载第三方dll所以运行效率要比多线程MD稍微高一点点,当然作为用户是完全感觉不到的。所以说如果打开一个程序目录,发现里面有类似msvcrtXX.dll,那么这个程序几乎可以肯定是用多线程MD方式编译的。

以上区别一言以蔽之就是多线程MT加载的是静态运行时库,属于C语言版本;而多线程MD版本加载是动态运行时库,属于微软版本。

总结:其实绝大多数软件都是采用多线程MD方式编译,例如QQ迅雷等等,如果找到他们目录很容易发现上面提到的运行时库。因为这样一来编译出来的文件小,所有运行时库统一,同时也让内存管理简单化,省去了跨模块内存访问带来的各种bug。

详解多线程MT和多线程MD的区别的更多相关文章

  1. HTTP详解(3)-http1.0 和http1.1 区别

    HTTP详解(3)-http1.0 和http1.1 区别 分类: 网络知识2013-03-17 16:51 1685人阅读 评论(0) 收藏 举报   目录(?)[+]   翻了下HTTP1.1的协 ...

  2. 详解 $_SERVER 函数中QUERY_STRING和REQUEST_URI区别

    详解 $_SERVER 函数中QUERY_STRING和REQUEST_URI区别 http://blog.sina.com.cn/s/blog_686999de0100jgda.html   实例: ...

  3. python爬虫---详解爬虫分类,HTTP和HTTPS的区别,证书加密,反爬机制和反反爬策略,requests模块的使用,常见的问题

    python爬虫---详解爬虫分类,HTTP和HTTPS的区别,证书加密,反爬机制和反反爬策略,requests模块的使用,常见的问题 一丶爬虫概述       通过编写程序'模拟浏览器'上网,然后通 ...

  4. 多线程MT和多线程MD的区别

    这段时间司在招实习生,而不管是远程的电话面试或者是实际现场面试中领导都喜欢问你这个问题,但是可惜的是能很好答上来的人很少.后来发现不管是应届的实习生,甚至有些实际参加工作几年的人也未必真的了解这个问题 ...

  5. MySQL系列详解八:MySQL多线程复制演示-技术流ken

    前言 Mysql 采用多线程进行复制是从 Mysql 5.6 开始支持的内容,但是 5.6 版本下有缺陷,虽然支持多线程,但是每个数据库只能一个线程,也就是说如果我们只有一个数据库,则主从复制时也只有 ...

  6. [转] 详解http和https的作用与区别

    PS: https就是http和TCP之间有一层SSL层,这一层的实际作用是防止钓鱼和加密.防止钓鱼通过网站的证书,网站必须有CA证书,证书类似于一个解密的签名.另外是加密,加密需要一个密钥交换算法, ...

  7. css学习--inline-block详解及dispaly:inline inline-block block 三者区别精要概括

    *知识储备: 内联元素:是不可以控制宽和高.margin等:并且在同一行显示,不换行. 块级元素:是可以控制宽和高.margin等,并且会换行. 1.inline-block 详解 (1)一句话就是在 ...

  8. input表单的type属性详解,不同type不同属性之间区别

    目标:详解表单input标签type属性常用的属性值 一.input标签和它的type属性 PS:input 元素可以用来生成一个供用户输入数据的简单文本框. 在默认的情况下, 什么样的数据均可以输入 ...

  9. 详解http和https的作用与区别

    PS: https就是http和TCP之间有一层SSL层,这一层的实际作用是防止钓鱼和加密.防止钓鱼通过网站的证书,网站必须有CA证书,证书类似于一个解密的签名.另外是加密,加密需要一个密钥交换算法, ...

随机推荐

  1. Dubbo服务暴露分析

    Dubbo的服务暴露是一个重要的特性,了解其机制很重要.之前有很多人写了有关的源代码分析,在本文中不再重新分析.官方文档中的一篇写的就很好,本文主要是有关内容进行补充与总结. 传送门:服务导出 为什么 ...

  2. BZOJ-2424: [HAOI2010]订货【费用流】

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1487  Solved: 1002[Submit][Status][Discuss] Descript ...

  3. POJ 2096 Collecting Bugs (概率DP,求期望)

    Ivan is fond of collecting. Unlike other people who collect post stamps, coins or other material stu ...

  4. 网页出现横向滚动条的原因可能是使用bootstrap不当引起

    Bootstrap的栅格布局超级方便我们写网页.但是在不是全体配合使用的情况下,会出现横向滚动条的现象. 什么叫不是配合使用的情况呢? >>一种情况是:你使用了row作为你的第一层父元素: ...

  5. ReviewBoard使用:添加SVN

    1.登录ReviewBoard,选择“Admin” 2.选择 “Repositores”,点击按钮“Add” 3.填写内容,然后点击按钮“SAVE”保存 Name:仓库名称(自己随意写) Hostin ...

  6. 占位 CP

    占位 CP include: CP403 CP404 CP405

  7. Spring5源码阅读环境搭建-gradle构建编译

      前沿:Spring系列生态十分丰富,涉及到各个方面.但是作为Spring生态的核心基础Spring,是最重要的环节,需要理解Spring的设计原理,我们需要解读源码.   在构建Spring源码阅 ...

  8. 线程锁Lock ,Rlock

    锁的引入: 我们查看官方文档:https://docs.python.org/3/library/threading.html#lock-objects 原语锁:threading.Lock 实现原始 ...

  9. yii csrf 配置

    csrf默认启用 全局配置 'components'=>array( 'request'=>array( // Enable Yii Validate CSRF Token 'enable ...

  10. Deepin安装常用软件

    Deepin安装常用软件 安装git sudo apt-get install git sudo是Debian系列以管理员运行的前缀 卸载软件 sudo apt-get remove package_ ...