首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VB >

一种取得Windows系统运行时间,且不同于GetTickCount的方法解决方案

2012-01-24 
一种取得Windows系统运行时间,且不同于GetTickCount的方法Windows系统的应用程序编程接口函数(API)都是使

一种取得Windows系统运行时间,且不同于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/c2d2370d-d506-441e-b3c0-5aa3a6bcd566.html

最近我偶然间发现一个高人提供的一个方法,感觉能弥补VB中GetTickCount函数的不足。代码如下:

VB code
Option ExplicitPrivate Declare Function osQueryPerformanceCounter Lib "kernel32" Alias "QueryPerformanceCounter" _                                                (lpPerformanceCount As Currency) As LongPrivate Declare Function osQueryPerformanceFrequency Lib "kernel32" Alias "QueryPerformanceFrequency" _                                                (lpFrequency As Currency) As LongPrivate Declare Function GetTickCount Lib "kernel32" () As Long'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%'函数功能:计算Windows自启动以来所经历的时间(s)'返回类型:Double类型,你可以修改它,也可以返回整形。''%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%Public Function Timer() As Double    Dim freq As Currency    Dim count As CurrencyOn Error GoTo errFun    osQueryPerformanceFrequency freq        '频率 相当于速度 v    osQueryPerformanceCounter count         '已发脉冲数 相当于距离 s    Timer = count / freq                    '计算时间 t=s/v    Exit FunctionerrFun:    Timer = 0End FunctionPrivate Sub Form_Load()    Text1.Text = ""    Text2.Text = ""    Timer1.Enabled = True    Timer1.Interval = 1000End Sub'%%%%%%%%%%%%%%%%%%%%%%'过程功能:使用两个方法计算系统启动时间,实际测试,两者值有点误差。''%%%%%%%%%%%%%%%%%%%%%%%Private Sub Timer1_Timer()    Text1.Text = Timer    Text2.Text = GetTickCount * 0.001End Sub


[解决办法]
我觉得最精确的是靠CPU计数器配合误差补偿算法。
在《深入理解计算机系统》里面有介绍。
[解决办法]
探讨
老兄顶的真是快啊!!!谢谢
这个貌似就是利用你说得方法来做得。

[解决办法]
探讨
呵呵,我那太高了,我水平差的远。。。

[解决办法]
顶。。。
[解决办法]
.................帮顶.
[解决办法]
在这里我个人感觉数学思维比编程技巧更重要啊…………………………
[解决办法]
打酱油,路过~~~~~~~~~
[解决办法]
计算机的脉冲估计是由晶体振荡器产生的确实不太精确,要想精确计时可以搞个原子钟啥的,几万年甚至几十万年的累计误差才1秒钟。
[解决办法]
嘿,昨天用家里的电脑玩游戏,玩了大概3、4个小时左右花屏了~~~
重启电脑用比较新版的 Everesthome 查看硬件温度~~~

无意中发现了它能显示系统第一次安装后到当前所经过的时间。
最下面还有一条信息提示说:此数据由系统事件计算所获得
[解决办法]
.................帮顶.
[解决办法]
探讨
唉!高手们除了顶就没有点说的?哪怕是否定的也可以啊。我就是看GetTickCount函数的范围被缩小了不爽,所以对这个问题有些纠结而已。。。

------解决方案--------------------


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

[解决办法]
感谢分享
[解决办法]

[解决办法]
多谢分享!
[解决办法]
study
[解决办法]
继续学习
[解决办法]
太高深了,都涉及天文啊,高人太多了!
[解决办法]
顶了 谢谢
[解决办法]
推荐了,恭喜顺带标记。
[解决办法]
打酱油,路过~~~~~~~~~
[解决办法]
11111111111111111111
[解决办法]
不是吧! 
这样也可以吗?
[解决办法]
太强悍了吧?
[解决办法]
没 发现有什么特别的,这个帖子不应该被推荐,让人觉得VB版太没前途了。


[解决办法]
厉害
[解决办法]
.................帮顶.[b][/b]
[解决办法]
呵呵 兄弟们谢了哦 .................顶.
[解决办法]
探讨
没 发现有什么特别的,这个帖子不应该被推荐,让人觉得VB版太没前途了。

[解决办法]
半夜过来路过一下就闪.........
[解决办法]
学习!
[解决办法]
学习!
[解决办法]
学习!
[解决办法]
有点意思,
[解决办法]
up
[解决办法]
探讨
这是高人的原文:


需要说明的一点是,如果你查阅API手册,你会发现API并不能识别Currency数据类型。在API手册中,osQueryPerformanceFrequencey要求的参数是一个Large_Integer的数据结构,该数据结构由两个Long类型的数据组成。Currency实际上也是按同样的方法来储存的。只不过在计算时被除以10000。因此你也可以写成:, (freq/10000) / (count/10000) = freq/count。关于上面的两个API函数,osQueryPerformanceFrequecy表示一秒内,计时器Tick了多少次;osQueryPerformanceCounter表示从开机到现在,计时器一共Tick了多少次。二者相除,就是从开机到现在过去了多少秒钟。


[解决办法]
打酱油
[解决办法]
负数你完全可以转换为正确的大整数..还这么麻烦?
[解决办法]
可以试试啊
[解决办法]
打酱油的
[解决办法]


数学思维比编程技巧更重要.
[解决办法]
学习
[解决办法]
没用过这个API
[解决办法]
VB 不懂~呵呵。
[解决办法]
学习拉!
[解决办法]
用汇编指令
[解决办法]
sf!!
[解决办法]
需要获取高精度的时间系统本身就提供了几个API呀,干嘛这么麻烦,去MSDN 查一下 QueryPerformanceCounter、QueryPerformanceFrequency
[解决办法]
ding
[解决办法]
ding
[解决办法]
那不叫修整, 所谓你说的负数,只是他的表现形式,就数据内容来看,他还是完整的正整数
只是人为的干预,让他以负数计数的方式显示出来而已
要做的只是将这个形式以自己的需要的方式,显示出来而已
[解决办法]

探讨
需要获取高精度的时间系统本身就提供了几个API呀,干嘛这么麻烦,去MSDN 查一下 QueryPerformanceCounter、QueryPerformanceFrequency

[解决办法]
那不叫修整, 所谓你说的负数,只是他的表现形式,就数据内容来看,他还是完整的正整数 
只是人为的干预,让他以负数计数的方式显示出来而已 
要做的只是将这个形式以自己的需要的方式,显示出来而已
[解决办法]
帮顶。。
[解决办法]
顶!顶!
[解决办法]
太深奥了,路过,顶一下
[解决办法]
x太深奥了,路过,顶一下
[解决办法]
概念性错误。
GetTickCount 计数就是以 49.71 天的固定周期进行循环,并不受调用程序是否支持无符号整数的影响。
即使你用 C 语言进行 0.1 秒的计时,也会出现相减结果为负数的情况。
即使改用高精度计时器,还是有循环周期的。

大跨度比较准确的计时用 Date() 和 Timer() 两个函数就足够了。
[解决办法]
好像不是很准。。。

[解决办法]
VB有没有DWORD,如果有的话,直接赋值
[解决办法]
顶。。。。。。。。。。。。。
[解决办法]
这是高人的原文: 


需要说明的一点是,如果你查阅API手册,你会发现API并不能识别Currency数据类型。在API手册中,osQueryPerformanceFrequencey要求的参数是一个Large_Integer的数据结构,该数据结构由两个Long类型的数据组成。Currency实际上也是按同样的方法来储存的。只不过在计算时被除以10000。因此你也可以写成:, (freq/10000) / (count/10000) = freq/count。关于上面的两个API函数,osQueryPerformanceFrequecy表示一秒内,计时器Tick了多少次;osQueryPerformanceCounter表示从开机到现在,计时器一共Tick了多少次。二者相除,就是从开机到现在过去了多少秒钟。 

[解决办法]
学习
[解决办法]
学习了 你写的太多了 我也不晓得你説什么
[解决办法]
学习中。。。。。。。。3Q
[解决办法]
我觉得最精确的是靠CPU计数器配合误差补偿算法
[解决办法]
学习中。。。。。。。。
------解决方案--------------------


mark
[解决办法]

探讨
负数你完全可以转换为正确的大整数..还这么麻烦?

[解决办法]
高精度计数器,我已经玩过了。不过,陈辉说的NtQuerySystemInformation,还没有玩过,今天回去玩玩!
[解决办法]
感谢楼主分享。

[解决办法]
ding
[解决办法]
学习
[解决办法]
关注
[解决办法]
在多核情况下时间可能会计算得不准的,osQueryPerformanceCounter 取的是一个晶振震动的次数,
但是有可能会出现一个核与其它核的晶振震动次数不一致的情况,这时计算就会出现问题,具体原因MSDN
上有解释的,所以用这两个函数时,一定要将进行记时的线程绑定到某个CPU上,绑定的API函数是:SetThreadIdealProcessor,很多网游的服务器和客户端的时间同步模块都会有这样的规定的
[解决办法]
留意老马 好久了 呵呵 iam begginer,but not gay,,
[解决办法]
```````````````````````````````````````
[解决办法]
写得很好
呵呵
[解决办法]
.................帮顶.
[解决办法]
新手上路
[解决办法]
long负数只是vb没有dword的概念,当long数据的4个字节共32位中的最高位为1时,vb就显示为负的,而且此时值是为该负数的补码,如果你需要dowrd值,那么在vb中定义一个能包含dword数据范围的数据类型,如currency,然后直接用“&H100000000+long负值”就可以得到dword表示的正值了。

[解决办法]
学习学习~~~~
[解决办法]
dasgfhgdfdh
[解决办法]
100

热点排行