精华内容
下载资源
问答
  • 多线程MT和多线程MD的区别 文章目录多线程MT和多线程MD的区别1 链接的运行时库不一样2 全局堆句柄不一样3 编译出来的PE文件大小区别4 运行效率5 总结 多线程MT加载的是静态运行时库,属于C语言版本。 而多线程MD...

    VS运行库多线程MT和多线程MD的区别

    多线程MT加载的是静态运行时库,属于C语言版本。

    而多线程MD版本加载是动态运行时库,属于微软版本。

    在工程属性窗体中选择配置属性,C++选项的代码生成多线程调试 DLL (/MDd)和多线程调试 DLL (/MTd)是Debug版本,后面没有d的是Release版本。

    1 链接的运行时库不一样

    多线程MT是 "multithread, static version ” 意思是多线程静态的版本,定义了它后,编译器把LIBCMT.lib 安置到OBJ文件中,让链接器使用LIBCMT.lib 处理外部符号;

    多线程MD是 "multithread- and DLL-specific version” ,意思是多线程DLL版本,定义了它后,编译器把 MSVCRT.lib 安置到OBJ文件中,它连接到DLL的方式是静态链接,实际上工作的库是MSVCRxx.DLL

    静态运行时库:LIBCMT.lib

    动态运行时库:MSVCRT.lib + MSVCRxx.DLL

    所以在使用多线程MT时候要配合静态库来使用,使用多线程MD的时候要配合动态库来使用

    2 全局堆句柄不一样

    当某项目以MT(静态链接库)的形式嵌入到多个项目,则可能造成运行时库的内存管理有多份;

    当多项目以MD(动态链接库)方式运作时,其内部会采用同一个堆,内存管理将被简化;

    如果是一个多线程MT编译方式的程序,你写一个dll,导出一个函数,参数设置为vector,然后在exe中调用,当导出函数结束时就会崩溃掉。其实原因很简单,就是因为初始化向量空间时malloc内存的过程在exe中,而vector析构时会free内存,申请和释放的内存空间不一致

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

    所以使用多线程MD的方式可以使得A模块中申请的内存到B模块中释放不会出问题,也就是解决跨模块内存管理的问题。

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

    多线程MT编译出来的文件体积要比多线程MD编译出来的大,因为MT是把对应的运行时库直接放到编译出来的PE文件当中,而MD却是运行的时候从第三方dll中获取运行时库,自己本身却不包含

    4 运行效率

    多线程MT编译出来的文件运行时不需要加载第三方dll所以运行效率要比多线程MD稍微高一点点,当然作为用户是完全感觉不到的

    5 总结

    目前市面上大部分的软件都使用的是多线程MD的方式,编译出来的文件小,所有运行时库统一,同时也让内存管理简单化,省去了跨模块内存访问带来的各种bug。

    展开全文
  • 多线程MT加载的是静态运行时库,属于C语言版本;而多线程MD版本加载是动态运行时库,属于微软版本。在工程属性窗体中选择配置属性,C++选项的代码生成多线程调试 DLL (/MDd)和多线程调试 DLL (/MTd)是Debug版本,...

    多线程MT加载的是静态运行时库,属于C语言版本;而多线程MD版本加载是动态运行时库,属于微软版本。在工程属性窗体中选择配置属性,C++选项的代码生成多线程调试 DLL (/MDd)和多线程调试 DLL (/MTd)是Debug版本,后面没有d的是Release版本。

    一、全局堆句柄不一样。

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

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

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

    二、链接的运行时库不同。

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

    三、编译出来的PE文件大小区别

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

    四、总结说明

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

    展开全文
  • 详解多线程MT和多线程MD的区别

    千次阅读 2016-12-05 11:17:36
    区别1:全局堆句柄不一样。...其实很简单测试,如果是一个多线程MT编译方式的程序,你写一个dll,导出一个函数,参数设置为vector,然后在exe中调用,当导出函数结束时就会崩溃掉。其实原因很简单,就是因为初始化

    区别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的区别。

    千次阅读 2018-03-09 13:16:02
    /MD、/MT的选择 1、为什么选择/MD,不选/MT? (1)程序就不需要静态链接运行时库,可以减小软件的大小;...(补充:如果我们软件有个DLL,采用/MT体积增加太,则可以考虑/MD + 自带系统运行时库) ...

    /MD、/MT的选择
          1、为什么选择/MD,不选/MT?
             (1)程序就不需要静态链接运行时库,可以减小软件的大小;
             (2)所有的模块都采用/MD,使用的是同一个堆,不存在A堆申请,B堆释放的问题;
       (3)用户机器可能缺少我们编译时使用的动态运行时库。(补充:如果我们软件有多个DLL,采用/MT体积增加太多,则可以考虑/MD + 自带系统运行时库)
          2、为什么选择/MT,不选择/MD?
             (1)有些系统可能没有程序所需要版本的运行时库,程序必须把运行时库静态链接上。
         (2)减少模块对外界的依赖。
          3、多个模块,必须选择相同的运行时库。



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

    区别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。 


    visual studio运行时库MT、MTd、MD、MDd的研究


    在开发window程序是经常会遇到编译好好的程序拿到另一台机器上面无法运行的情况,这一般是由于另一台机器上面没有安装相应的运行时库导致的,那么这个与编译选项MT、MTd、MD、MDd有什么关系呢?这是msdn上面的解释:

    MTmutithread,多线程库,编译器会从运行时库里面选择多线程静态连接库来解释程序中的代码,即连接LIBCMT.lib库

    MTdmutithread+debug,多线程调试版,连接LIBMITD.lib库

    MDMT+DLL,多线程动态库,连接MSVCRT.lib库,这是个导入库,对应动态库为MSVCRT.dll

    MDd MT+DLL+debug,多线程动态调试库,连接MSVCRTD.lib库,对应动态库为MSVCRTD.dll

    开发多线程程序时(单线程本文不做讨论),需要选择MT、MTd、MD、MDd其中的一个。

     

    对于MT/MTd,由于连接运行时库是LIBCMT.lib/LIBCMTD.lib,这两个库是静态库,所以此种方式编译的程序,移到另一台机器上面也可以正常运行。

    但是对于MD/MDd,连接的是动态库,所以如果另一台机器上没有MSVCRT.dll/MSVCRTD.dll时,就提示缺少动态库这样的错误。

     

    曾经犯这样的错误,以为以MT/MTd方式编译,程序对所有的库都是静态链接的,其实错了,它只能决定运行时库是动态链接还是静态链接,对用户自己写的库或其他第三方库,其连接方式取决于代码(显式连接动态库Loadlibrary)或所提供的lib文件(为导入库还是静态库),移动程序到别的机器上时,还是要带上所需要的动态库的。


    展开全文
  • 多线程MT和MD的区别

    2020-04-09 18:35:53
    /MD、/MT的选择 1、为什么选择/MD,不选/MT? (1)程序就不需要静态链接运行时库,可以减小软件的大小;...(补充:如果我们软件有个DLL,采用/MT体积增加太,则可以考虑/MD+自带系统运行时库...
  • 转载 关于多线程MT和MD的区别。

    千次阅读 2014-12-19 13:28:14
    这段时间司在招实习生,而不管是远程的电话面试或者是实际现场面试中领导都喜欢问你这个问题,但是可惜的是能很好答上来的人很少。后来发现不管是应届的实习生,...前者很容易有理解,每个线程创建的时候在CreateThread
  • 详解多线程MT 和 MD

    2014-12-30 11:29:13
    今天看到一篇帖子,对此方面解释的不错,再此记录一下: 区别1:全局堆句柄不一样。...其实很简单测试,如果是一个多线程MT编译方式的程序,你写一个dll,导出一个函数,参数设置为vector,然后
  • 一种语言的开发环境往往会附带有语言库,...按照单线程/多线程,可以分为单线程版本和多线程版本(但是目前VS中已不提供单线程版本了) 在调试模式下,使用调试运行库:多线程调试(/MTd)、多线程调试DLL(/MDd) ...
  • VC编译选项 多线程(/MT)多线程调试(/MTd)多线程 DLL (/MD)多线程调试 DLL (/MDd)C 运行时库 库文件Single thread(static link) ML libc.libDebug single thread(static link) MLd libcd.libMultiThrea...
  • VC编译选项 多线程(/MT) 多线程调试(/MTd) 多线程 DLL (/MD) 多线程调试 DLL (/MDd)
  • 用于Rust和WebAssembly的多线程库。 wasm-mt帮助您创建和执行基于Web Worker的线程。 您可以简单地使用Rust闭包对线程进行编程,并使用async/await对其进行编排。 例子 wasm-mt-pool wasm-mt基于wasm-mt线程池库。...
  • libpcap库是不支持多线程的,本例中使用两个线程分别进行抓包和处理包,并使用boost把抓到的包序列化,作为消息存放在ActiveMQ中
  • Java多线程

    千次阅读 多人点赞 2019-05-04 22:28:49
    一、多线程的概念 想要知道什么是多线程?就会引出线程的概念,而线程和进程之间又是息息相关的。 进程:操作系统中一个程序的执行周期称为一个进程。 线程:一个程序同时执行多个任务。通常,每一个任务就称为...
  • JAVA多线程面试题

    2019-07-11 18:15:21
    Thread MyThread = new Thread(mt,“线程名”); //sleep()使该线程进入阻塞状态,本身不会释放锁 MyThread .sleep(millis);//毫秒数 MyThread .yield()//放弃cpu使用权利,使该线程进入就绪状态 MyThread.getState();...
  • mt-aws-glacier:将Perl多线程多部分同步到Amazon Glacier
  • 自己编译的lib库,及例程,下载后可直接编译运行; 此lib不适用于控制台程序; 是专门为MFC编译的;有问题直接给我留言;
  • libpcap-MT:一种多线程的通用数据包捕获库
  • 特征 互斥体 线 支持的操作系统 Linux 苹果系统 视窗 建造要求 C99编译器
  • FUSE-MT文档这段代码是Rust FUSE板条箱的包装,并增加了以下内容:在线程上调度系统调用,因此FUSE-MT文档这段代码是Rust FUSE板条箱的包装,并添加了以下附加物:在线程上调度系统调用,以便例如I / O不会...
  • 这段代码使用欧几里德距离实现了基本的kmeans算法,其计算速度使用C/C++和多线程进行了优化。 当样本数量和特征维数很大时,此代码将明显快于 Matlab 工具箱中的代码和其他高效实现(如 litekmeans( ...
  • VS编译Release时MT出错

    2017-05-02 05:58:57
    用VS编译Release时,运行库选择 【多线程/MT】(注明,必须选择此项),但却报错 错误,错误信息如下: C1189 #error: Please use the /MD switch for _AFXDLL builds 请问是哪里出问题了,如何解决?
  • 这段代码实现了基本的GMM算法,支持全值或仅对角非零值的多个协方差矩阵,其计算速度使用C/C++和多线程进行了优化。 当样本数量和特征维度很大时,这段代码会比 Matlab 工具箱中的代码快很多例如,对于17维76800个...
  • 在Unix平台上,多线程程序必须用特殊的方式连接,比如使用特殊的libc,安装程序将会创建另外一个库libqt-mt并且因此线程程序必须和这个库进行连接(使用-lqt-mt)而不是标准的Qt库。 在两个平台上,你都应该定义...
  •  内核系列,它是针对高性能和成本敏感的嵌入式应用的一种革命新性多线程解决方案。34K 核心系列是首个执行MIPS? MT ASE,并利用包括 MIPS DSP ASE 的成熟功的 24KE? 微架构的产品。34K 内核的多线程能力...
  • QT 5.15.0 静态编译好的目录打包,包含所有的lib、bin、include、plugin目录等...完全静态编译方式:MT多线程),不需要任何外部运行库,包括QT和VC运行库 64位版本,支持VS2017和VS2019,QWebEngine不是静态编译的

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 24,574
精华内容 9,829
关键字:

多线程mt