VC++多线程下内存操作的优化(2)
解决方法
本方法要求多线程程序是用VC++编写的,并且是动态链接到C运行库的。要求NT系统所安装的VC++运行库文件msvcrt.dll的版本号是6,所安装的service pack的版本是5以上。如果程序是用VC++ v6.0以上版本编译的,即使多线程程序和libcmt.lib是静态链接,本方法也可以使用。
当一个VC++程序运行时,C运行库被初始化,其中一项工作是确定要使用的堆管理器,VC++ v6.0运行库既可以使用其自己内部的堆管理函数,也可以直接调用操作系统的堆管理函数(HeapAlloc()系列的函数),在__heap_select()函数内部分执行以下三个步骤:
1、检查操作系统的版本,如果运行于NT,并且主版本是5或更高(Window 2000及以后版本),就使用HeapAlloc()。
2、查找环境变量__MSVCRT_HEAP_SELECT,如果有,将确定使用哪个堆函数。如果其值是__GLOBAL_HEAP_SELECTED,则会改变所有程序的行为。如果是一个可执行文件的完整路径,还要调用GetModuleFileName()检查是否该程序存在,至于要选择哪个堆函数还要查看逗号后面的值,1表示使用HeapAlloc(),2表示使用VC++ v5的堆函数,3表示使用VC++ v6的堆函数。
3、检测可执行文件中的链接程序标志,如果是由VC++ v6或更高的版本创建的,就使用版本6的堆函数,否则使用版本5的堆函数。
那么如何提高程序的性能?如果是和msvcrt.dll动态链接的,保证这个dll是1999年2月以后,并且安装的service pack的版本是5或更高。如果是静态链接的,保证链接程序的版本号是6或更高,可以用quickview.exe程序检查这个版本号。要改变所要运行的程序的堆函数的选取,在命令行下键入以下命令:
set __MSVCRT_HEAP_SELECT=__GLOBAL_HEAP_SELECTED,1
以后,所有从这个命令行运行的程序,都会继承这个环境变量的设置。这样,在堆操作时都会使用HeapAlloc()。如果让所有的程序都使用这些速度更快的堆操作函数,运行控制面板的“系统”程序,选择“环境”,点取“系统变量”,输入变量名和值,然后按“应用”按钮关闭对话框,重新启动机器。
按照微软的说法,可能有一些用VC++ v6以前版本编译程序,使用VC++ v6的堆管理器会出现一些问题。如果在进行以上设置后遇到这样的问题,可以用一个批处理文件专门为这个程序把这个设置去掉,例如:
set __MSVCRT_HEAP_SELECT=c:program filesmyappmyapp.exe,1 c:inuggyapp.exe,2
测试
为了验证在多处理器下的效果,编了一个测试程序heaptest.c。该程序接收三个参数,第一个参数表示线程数,第二个参数是所申请的内存的最大值,第三个参数每个线程申请内存的次数。
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <process.h>
#include <stdio.h>
#include <stdlib.h>
/* compile with cl /MT heaptest.c */
/* to switch to the system heap issue the following command
before starting heaptest from the same command line
set __MSVCRT_HEAP_SELECT=__GLOBAL_HEAP_SELECTED,1 */
/* structure transfers variables to the worker threads */
typedef struct tData
{
- 上一篇:BMP位图文件结构及VC操作
- 下一篇:在VC++中访问和修改系统注册表