详解多线程MT和多线程MD的区别
区别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的区别相关推荐
- Java implement意思_详解JAVA中implement和extends的区别
详解JAVA中implement和extends的区别 发布于 2020-4-14| 复制链接 摘记: 详解JAVA中implement和extends的区别extends是继承父类,只要那个类不是声 ...
- java中implement_详解JAVA中implement和extends的区别
详解JAVA中implement和extends的区别 extends是继承父类,只要那个类不是声明为final或者那个类定义为abstract的就能继承,Java中不支持多重继承,但是可以用接口来实 ...
- vlan标签详解 access、trunk和hybrid的区别
vlan标签详解 access.trunk和hybrid的区别 我们知道,不同网段间需要通过路由转发才能通信: 那在同一网段不同vlan之间的PC,是不能互相通信的.其实这并不是绝对的.了解vlan的 ...
- c语言中的fscanf是啥意思,详解C语言中fgets和fscanf区别
fscanf函数是C语言的文件格式读取函数的方法之一,它使用空格.制表符和回车来分割不同的单词,这样可以让我们使用起来更方便,下面就让爱站技术频道小编带你来学习详解C语言中fgets和fscanf区别 ...
- 详解Javascript本地存储的方式、区别及应用场景
详解Javascript本地存储的方式.区别及应用场景 一.方式 javaScript本地缓存的方法我们主要讲述以下四种: cookie sessionStorage localStorage ind ...
- 多线程MT和多线程MD的区别
多线程MT加载的是静态运行时库,属于C语言版本:而多线程MD版本加载是动态运行时库,属于微软版本.在工程属性窗体中选择配置属性,C++选项的代码生成多线程调试 DLL (/MDd)和多线程调试 DLL ...
- 详解python正则\b和\B的区别
不知道你会不会出现这种错误, print(re.findall('er\b','never')) 输出结果却为空? 如果你出现这种问题,说明你没有转义,试着输入以下语句 print(re.findal ...
- 代理模式详解(静态代理和动态代理的区别以及联系)
原文链接:https://www.cnblogs.com/takumicx/p/9285230.html 1. 前言 代理模式可以说是生活中处处可见.比如说在携程上定火车票,携程在这里就起到了一个代理 ...
- 详解http和https的作用与区别
PS: https就是http和TCP之间有一层SSL层,这一层的实际作用是防止钓鱼和加密.防止钓鱼通过网站的证书,网站必须有CA证书,证书类似于一个解密的签名.另外是加密,加密需要一个密钥交换算法, ...
最新文章
- Linux运维系统工程师系列---16
- 利用css3实现jQuery中的slideDown和slideUp效果
- 基于Java的RDMA高性能通信库(五):JXIO
- 【安全漏洞】简要分析复现了最近的ProxyShell利用链
- html 如何去除浮动,CSS浮动? 如何清除浮动?
- 疫情之下,使用FRP实现内网穿透,远程连接公司电脑进行办公
- Nacos部署中的一些常见问题汇总
- Hemberg-lab单细胞转录组数据分析(一)
- 16-elasticsearch6.x {“error“:“Content-Type header [application/x-www-form-urlencoded] is not support
- 树状数组求区间和 和 单点更新
- 苹果Mac电脑硬件温度监测工具:TG Pro
- 20162313苑洪铭第四周学习小结
- c语言模糊pid算法实例,模糊PID的c语言算法.docx
- 政府网站防篡改解决方案
- ENVI学习总结(九)——图像裁剪
- java实现九九乘法表
- 数据平滑处理——log1p()和exmp1()
- 电气图纸关于号码管的命名规则
- 湄洲岛风光-鹅尾神石园
- 百度oCPC一键联调激活教程?api怎么对接?
热门文章
- java计算机毕业设计建筑劳务监管平台MyBatis+系统+LW文档+源码+调试部署
- k2677场效应管参数引脚_常用场效MOS应管参数大全-电压参数表图文
- android大字体桌面,大图标大字体 Android老人机桌面试玩
- 试装memcachedb,整理了下安装过程【转】
- OEC管理法(转载)
- linux ethtool 命令详解
- 125KHz唤醒功能2.4GHz单发射芯片-Si24R2H
- 差速驱动机器人轮间距校准
- 思维导图MindMaster 安装
- 【Windows Server 2019】发布服务器 | 远程桌面服务的安装与配置 Ⅰ——理论,实验拓扑和安装基于RemoteAPP的RDS