几何尺寸与公差论坛------致力于产品几何量公差标准GD&T (GDT:ASME)|New GPS(ISO)研究/CAD设计/CAM加工/CMM测量  


返回   几何尺寸与公差论坛------致力于产品几何量公差标准GD&T (GDT:ASME)|New GPS(ISO)研究/CAD设计/CAM加工/CMM测量 » 仿射空间:CAX软件开发(三)二次开发与程序设计 » 程序设计 » vc编程
用户名
密码
注册 帮助 会员 日历 银行 搜索 今日新帖 标记论坛为已读


回复
 
主题工具 搜索本主题 显示模式
旧 2010-04-14, 09:15 PM   #1
huangyhg
超级版主
 
huangyhg的头像
 
注册日期: 04-03
帖子: 18592
精华: 36
现金: 249466 标准币
资产: 1080358888 标准币
huangyhg 向着好的方向发展
默认 一种取得Windows系统运行时间,且不同于GetTickCount的方法[问题点数:100分,结帖人:Veron_04]

http://topic.csdn.net/u/20090904/23...f5bb3ad574.html
Windows系统的应用程序编程接口函数(API)都是使用C/C++语言编写的,VB中使用系统API函数需要改写声明。
GetiTickCount函数的含义是:取得自Windows系统启动以来到现在所经过的时间(单位:ms)。
在VB6.0中,API函数:
GetTickCount的声明如下:Private Declare Function GetTickCount Lib "kernel32" () As Long
在Windows中,该函数的原型是:DWORD GetiTickCount

我们可以发现在VB系统下,Gettickcount返回的是Long类型,长4个字节,而在WIndows下,GetTickCount返回的是DWORD类型,长4个字节的无符号数据类型。DWORD类型的数据范围是:0 ~ 2^32。
Long类型的数据范围是:-2147483648~2147483647,作为GetTickCount函数的返回值,只能是:0~2147483647,经过计算大约是:24.86天,也就是说,使用VB编制的系统在使用了24.86天以后,使用GetTickCount读回来的值就是负数了!具体原因请参考:http://topic.csdn.net/u/20090708/20...a3a6bcd566.html

最近我偶然间发现一个高人提供的一个方法,感觉能弥补VB中GetTickCount函数的不足。代码如下:
Windows系统的应用程序编程接口函数(API)都是使用C/C++语言编写的,VB中使用系统API函数需要改写声明。
GetiTickCount函数的含义是:取得自Windows系统启动以来到现在所经过的时间(单位:ms)。
在VB6.0中,API函数:
GetTickCount的声明如下:Private Declare Function GetTickCount Lib "kernel32" () As Long
在Windows中,该函数的原型是:DWORD GetiTickCount

我们可以发现在VB系统下,Gettickcount返回的是Long类型,长4个字节,而在WIndows下,GetTickCount返回的是DWORD类型,长4个字节的无符号数据类型。DWORD类型的数据范围是:0 ~ 2^32。
Long类型的数据范围是:-2147483648~2147483647,作为GetTickCount函数的返回值,只能是:0~2147483647,经过计算大约是:24.86天,也就是说,使用VB编制的系统在使用了24.86天以后,使用GetTickCount读回来的值就是负数了!具体原因请参考:http://topic.csdn.net/u/20090708/20...a3a6bcd566.html

最近我偶然间发现一个高人提供的一个方法,感觉能弥补VB中GetTickCount函数的不足。代码如下:
VB code OptionExplicit
Private Declare Function osQueryPerformanceCounter Lib "kernel32" Alias "QueryPerformanceCounter" _
(lpPerformanceCount
AsCurrency) AsLong
Private Declare Function osQueryPerformanceFrequency Lib "kernel32" Alias "QueryPerformanceFrequency" _
(lpFrequency
AsCurrency) AsLong
Private Declare Function GetTickCount Lib "kernel32" () AsLong
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
'
函数功能:计算Windows自启动以来所经历的时间(s)
'
返回类型:Double类型,你可以修改它,也可以返回整形。
'
'
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
PublicFunctionTimer() AsDouble
Dim freq AsCurrency
Dim count AsCurrency
OnErrorGoTo errFun
osQueryPerformanceFrequency freq
'频率 相当于速度 v
osQueryPerformanceCounter count '已发脉冲数 相当于距离 s
Timer= count / freq '计算时间 t=s/v
ExitFunction
errFun:
Timer=0
End Function

PrivateSub Form_Load()
Text1.Text
=""
Text2.Text
=""
Timer1.Enabled
=True
Timer1.Interval
=1000
End Sub
'%%%%%%%%%%%%%%%%%%%%%%
'
过程功能:使用两个方法计算系统启动时间,实际测试,两者值有点误差。
'
'
%%%%%%%%%%%%%%%%%%%%%%%
PrivateSub Timer1_Timer()
Text1.Text
=Timer
Text2.Text
= GetTickCount *0.001
End Sub
__________________
借用达朗贝尔的名言:前进吧,你会得到信心!
[url="http://www.dimcax.com"]几何尺寸与公差标准[/url]
huangyhg离线中   回复时引用此帖
GDT自动化论坛(仅游客可见)
旧 2010-04-14, 09:16 PM   #2
huangyhg
超级版主
 
huangyhg的头像
 
注册日期: 04-03
帖子: 18592
精华: 36
现金: 249466 标准币
资产: 1080358888 标准币
huangyhg 向着好的方向发展
默认 回复: 一种取得Windows系统运行时间,且不同于GetTickCount的方法[问题点数:100分,结帖人:Veron_04]

这是高人的原文:


需要说明的一点是,如果你查阅API手册,你会发现API并不能识别Currency数据类型。在API手册中,osQueryPerformanceFrequencey要求的参数是一个Large_Integer的数据结构,该数据结构由两个Long类型的数据组成。Currency实际上也是按同样的方法来储存的。只不过在计算时被除以10000。因此你也可以写成:, (freq/10000) / (count/10000) = freq/count。关于上面的两个API函数,osQueryPerformanceFrequecy表示一秒内,计时器Tick了多少次;osQueryPerformanceCounter表示从开机到现在,计时器一共Tick了多少次。二者相除,就是从开机到现在过去了多少秒钟。
__________________
借用达朗贝尔的名言:前进吧,你会得到信心!
[url="http://www.dimcax.com"]几何尺寸与公差标准[/url]
huangyhg离线中   回复时引用此帖
旧 2010-04-14, 09:16 PM   #3
huangyhg
超级版主
 
huangyhg的头像
 
注册日期: 04-03
帖子: 18592
精华: 36
现金: 249466 标准币
资产: 1080358888 标准币
huangyhg 向着好的方向发展
默认 回复: 一种取得Windows系统运行时间,且不同于GetTickCount的方法[问题点数:100分,结帖人:Veron_04]

我觉得最精确的是靠cpu计数器配合误差补偿算法。
在《深入理解计算机系统》里面有介绍。
__________________
借用达朗贝尔的名言:前进吧,你会得到信心!
[url="http://www.dimcax.com"]几何尺寸与公差标准[/url]
huangyhg离线中   回复时引用此帖
旧 2010-04-14, 09:17 PM   #4
huangyhg
超级版主
 
huangyhg的头像
 
注册日期: 04-03
帖子: 18592
精华: 36
现金: 249466 标准币
资产: 1080358888 标准币
huangyhg 向着好的方向发展
默认 回复: 一种取得Windows系统运行时间,且不同于GetTickCount的方法[问题点数:100分,结帖人:Veron_04]

引用 13 楼 citybird 的回复:
计算机的脉冲估计是由晶体振荡器产生的确实不太精确,要想精确计时可以搞个原子钟啥的,几万年甚至几十万年的累计误差才1秒钟。


错。这个牵涉到天文学上很复杂的概念,简单地说是这样的:
物理上,我们要求一秒的长度是固定的。
生活中我们要求一天的长度是 24x3600 秒。
然而,很不幸的是,一天的长度并不固定,首先一天的定义应该是太阳两次通过子午线的间隔,然而地球的公转速度在一年内是不均匀的,冬天快夏天慢(开普勒定律)。就公转本身还存在进动和章动。
另外地球由于受到月球潮汐摩擦力的作用,自转速度会减慢,大约一个世纪几毫秒。
除此之外,还有不规则的变动,无法预计。
因此,每隔几年,我们就需要添加一个正闰秒或者负闰秒来消除这种误差。
所以时间只能由授时中心发布。
__________________
借用达朗贝尔的名言:前进吧,你会得到信心!
[url="http://www.dimcax.com"]几何尺寸与公差标准[/url]
huangyhg离线中   回复时引用此帖
旧 2010-04-14, 09:18 PM   #5
huangyhg
超级版主
 
huangyhg的头像
 
注册日期: 04-03
帖子: 18592
精华: 36
现金: 249466 标准币
资产: 1080358888 标准币
huangyhg 向着好的方向发展
默认 回复: 一种取得Windows系统运行时间,且不同于GetTickCount的方法[问题点数:100分,结帖人:Veron_04]

需要获取高精度的时间系统本身就提供了几个API呀,干嘛这么麻烦,去MSDN 查一下 QueryPerformanceCounter、QueryPerformanceFrequency
__________________
借用达朗贝尔的名言:前进吧,你会得到信心!
[url="http://www.dimcax.com"]几何尺寸与公差标准[/url]
huangyhg离线中   回复时引用此帖
旧 2010-04-14, 09:18 PM   #6
huangyhg
超级版主
 
huangyhg的头像
 
注册日期: 04-03
帖子: 18592
精华: 36
现金: 249466 标准币
资产: 1080358888 标准币
huangyhg 向着好的方向发展
默认 回复: 一种取得Windows系统运行时间,且不同于GetTickCount的方法[问题点数:100分,结帖人:Veron_04]

引用 60 楼 soft_dep 的回复:
需要获取高精度的时间系统本身就提供了几个API呀,干嘛这么麻烦,去MSDN 查一下 QueryPerformanceCounter、QueryPerformanceFrequency



直接用NtQuerySystemInformation不是更好
省却了函数之间的调用
__________________
借用达朗贝尔的名言:前进吧,你会得到信心!
[url="http://www.dimcax.com"]几何尺寸与公差标准[/url]
huangyhg离线中   回复时引用此帖
旧 2010-04-14, 09:19 PM   #7
huangyhg
超级版主
 
huangyhg的头像
 
注册日期: 04-03
帖子: 18592
精华: 36
现金: 249466 标准币
资产: 1080358888 标准币
huangyhg 向着好的方向发展
默认 回复: 一种取得Windows系统运行时间,且不同于GetTickCount的方法[问题点数:100分,结帖人:Veron_04]

高精度计数器,我已经玩过了。不过,陈辉说的NtQuerySystemInformation,还没有玩过,今天回去玩玩!
__________________
借用达朗贝尔的名言:前进吧,你会得到信心!
[url="http://www.dimcax.com"]几何尺寸与公差标准[/url]
huangyhg离线中   回复时引用此帖
旧 2010-04-14, 09:19 PM   #8
huangyhg
超级版主
 
huangyhg的头像
 
注册日期: 04-03
帖子: 18592
精华: 36
现金: 249466 标准币
资产: 1080358888 标准币
huangyhg 向着好的方向发展
默认 回复: 一种取得Windows系统运行时间,且不同于GetTickCount的方法[问题点数:100分,结帖人:Veron_04]

在多核情况下时间可能会计算得不准的,osQueryPerformanceCounter 取的是一个晶振震动的次数,
但是有可能会出现一个核与其它核的晶振震动次数不一致的情况,这时计算就会出现问题,具体原因MSDN
上有解释的,所以用这两个函数时,一定要将进行记时的线程绑定到某个CPU上,绑定的API函数是:SetThreadIdealProcessor,很多网游的服务器和客户端的时间同步模块都会有这样的规定的
__________________
借用达朗贝尔的名言:前进吧,你会得到信心!
[url="http://www.dimcax.com"]几何尺寸与公差标准[/url]
huangyhg离线中   回复时引用此帖
旧 2010-04-14, 09:20 PM   #9
huangyhg
超级版主
 
huangyhg的头像
 
注册日期: 04-03
帖子: 18592
精华: 36
现金: 249466 标准币
资产: 1080358888 标准币
huangyhg 向着好的方向发展
默认 回复: 一种取得Windows系统运行时间,且不同于GetTickCount的方法[问题点数:100分,结帖人:Veron_04]

引用 96 楼 sulipeng007 的回复:
long负数只是vb没有dword的概念,当long数据的4个字节共32位中的最高位为1时,vb就显示为负的,而且此时值是为该负数的补码,如果你需要dowrd值,那么在vb中定义一个能包含dword数据范围的数据类型,如currency,然后直接用“&H100000000+long负值”就可以得到dword表示的正值了。
__________________
借用达朗贝尔的名言:前进吧,你会得到信心!
[url="http://www.dimcax.com"]几何尺寸与公差标准[/url]
huangyhg离线中   回复时引用此帖
回复


主题工具 搜索本主题
搜索本主题:

高级搜索
显示模式

发帖规则
不可以发表新主题
不可以回复主题
不可以上传附件
不可以编辑您的帖子

vB 代码开启
[IMG]代码开启
HTML代码关闭



所有的时间均为北京时间。 现在的时间是 12:42 PM.


于2004年创办,几何尺寸与公差论坛"致力于产品几何量公差标准GD&T | GPS研究/CAD设计/CAM加工/CMM测量"。免责声明:论坛严禁发布色情反动言论及有关违反国家法律法规内容!情节严重者提供其IP,并配合相关部门进行严厉查处,若內容有涉及侵权,请立即联系我们QQ:44671734。注:此论坛须管理员验证方可发帖。
沪ICP备06057009号-2
更多