全部文章 | Selenium | 测试管理 | 测试技术学习 | 韩语学习 | JamesStudyRuby | 我的生活 | 软件开发

作者: jameswang   发表日期: 2006-03-06 21:35   复制链接




下文是本人在公司技术月刊发表的一片文章。

前几周,OceanRay在论坛中问了关于vb中实现线程的问题。当时我比较忙,只是匆匆给他找了一点参考资料。当巴乔找到我,让我为第一期电子月刊写一篇windows专题的时候,我首先想到了OceanRay的问题。当时,我踌躇满志地想花点时间,写出一个真正有效的VB的多线程例子。最后还是放弃了。果真如Daniel Appleman所说,尽管VB允许调用Windows API来做一些高级工作,但是,在VB中使用线程相关API是十分危险的。几个小时的程序调试,换来的是不停的莫名其妙的内存访问错误。因为我比较缺乏线程编程经验,不得已,换了一个简单一点的题目。 m;*!膠Lo=  
在网上粗略地搜了一下,发现虽然有很多代码介绍了用Timer控件来实现动画效果,但是好像没有人试图用Timer控件来模拟线程。即便有相关的讨论(参考文献[3]),也存在很多质疑。根据以前项目的经验,我写了一个小例子,用VB的Timer控件来模拟多线程。 鵬杠ac+衾  

1.什么是多线程?多线程比单线程“快吗”? L!P\偟  
线程是操作系统运行程序的基本单元。单线程是指一个程序在一个线程中运行。多线程是指一个程序启动多个线程来“同时”执行代码片断。请注意这里的同时是加了引号的。因为那是人类的错觉而已。对于一个单CPU的计算机,根本不存在“同时”这个概念。因为同一时间点,CPU只能执行某个线程的一个指令。举个例子,你打算在程序中做10件相同的任务。如果每个任务要花费1秒。那么,在单线程程序中,总共花费的时间就是10秒。如果用户通过点击按钮来启动任务,那么,他就必须在10秒钟之后才能使用这个程序的其他功能。假如你把10件任务放在10个线程中来执行,效果完全不同了。操作系统会花费了1秒钟在这些线程之间进行调度。那么,所有任务执行所用的时间就是11秒。由于使用了多线程,用户点击按钮之后可以马上使用其它功能。所以,在运行时间上,多线程要比单线程慢。但是,在用户响应时间上,多线程遥遥领先。

2.Timer控件是在创建另外一个线程来执行代码的吗? 虿 #  
回答是否定的。让我们来看个例子就知道了。

Private Sub Timer1_Timer(Index As Integer) x飇杔頋  
    Dim i As Long h铷,N)圶  
    For i = 0 To 100000 鏣钷Nsu   
        ‘DoEvents 朞{ 2偙G0  
        Text1.Text = CStr(i) 述l郳8z9  
    Next i ?懍%M鶶縹e  
End Sub

Timer1的Timer事件函数中,有一个大循环。

Private Sub Command1_Click() *谱颋殔F  
    MsgBox "Interrupted!" WEI N  
End Sub

霧'撻厬pX  
代码1

3@5$呡蛤  
当Timer开始运行后,我们点击Command1,画面没有反应。当Timer1一次执行完毕之后,消息框突然弹了出来。 =E┛W馍V  
结论:VB的代码都是运行在一个线程之中的。Timer控件也不例外。我们还可以做一个实验证明Timer并不是使用多线程。将Timer1的Interval属性设置为1(相当于1毫秒),结果,Timer1并没有一秒钟执行了1000次。实际的Interval是大循环执行所花费的时间。

3.DoEvents——VB的“软中断” L2LH 枙va  
当我们把代码1中DoEvents的注释去掉后,发现程序的表现不一样了。循环开始后,画面依然响应用户的动作。当点击Command1时,消息框立即弹出,Timer1的事件也立刻停止执行。当消息框关闭后,Timer1的时间又恢复执行。 {鹛E>\倌K  
结论:VB中的DoEvents关键字与线程中的Suspend或者Sleep的作用很相似。都是让当前代码段让出CPU时间给其他代码。不同之处在于线程是操作系统低层的支持,效率高;而DoEvents是利用windows的消息系统实现的“软中断”。

4.多Timer对多线程 e壒鑳猍  
通常的多线程程序,都创建不止一个线程。为了模拟真正的多线程,我们需要在代码中动态增加Timer的数量。

Private WithEvents newTimer As VB.Timer W,U斍Q胤  
…… 炐=6挴8  
Set newTimer = Controls.Add("vb.Timer", "Timer2", Form1) H╲動揰  
…… 妗繕k<燜  
Private Sub newTimer_Timer() u獫}n&o  
End Sub 葇霥!  
……

p)窽族⒆  
代码2

通过如上方式,我们可以在Form1中动态添加Timer2。虽然,每个Timer执行的代码逻辑都可以不同,但是,由于所有的逻辑事先写好,所以不能实现真正的动态添加。后来,我找到了参考文献[4]中的代码,感觉可以实现真正的动态添加。遗憾的是时间仓促,没有来得及实践。

Private Sub Timer1_Timer() ;藵"  
    work Timer1.Name 稓螬J琂;t  
End Sub

Private Sub newTimer_Timer() 楄(WI ル  
    work newTimer.Name &(!熑3  
End Sub

Private Sub work(name As String) +1(cR  
    Debug.Print "in--------------------------" + name 倉M嗛侃J1o  
    吖"rx岸  
    Dim i As Long 涷棐  
    For i = 0 To 1000 挄苚`<j6J*  
        DoEvents 儓L閝w繶  
        Text1.Text = CStr(i) ,9f軾x  
    Next i xv,漃d  
    Debug.Print "out-------------------------" + name P鋆$茞W&)  
End Sub

G撑2pI  
代码3

我在两个Timer事件中调用同一个函数,参数分别是两个Timer的名字。以下是控制台的输出: k卙侌轕g  
…… K>  
in--------------------------Timer1 )苯淘Τ,韞  
in--------------------------newTimer F(賮繾  
out-------------------------newTimer *\D?o  
out-------------------------Timer1 R岪=阣C/  
in--------------------------newTimer : -0④  
in--------------------------Timer1 cis`^y鲣  
out-------------------------Timer1 蟍 K,  
out-------------------------newTimer y烤T朼q@I  
in--------------------------Timer1 ⺧w%洝蠟+  
in--------------------------newTimer 蛄.9琂鵡怹  
out-------------------------newTimer u=E ,睺  
out-------------------------Timer1 C .a諠N_  
in--------------------------newTimer ?Z%  
in--------------------------Timer1 ;21釴㏄  
out-------------------------Timer1 /忽议真沎  
out-------------------------newTimer 酰敻蹢讆  
in--------------------------Timer1 禩椥榥状  
in--------------------------newTimer 曷動?V蕪  
out-------------------------newTimer "b #Ir3=  
out-------------------------Timer1 耟v5用  
……

%p闸'  
代码4

结论:通过在VB的Timer控件中灵活使用DoEvents,我们模拟多线程的效果。

5.Timer中的同步 )瘮.箋 A  
在使用windows线程API的时候,我们可以使用信号灯或者临界区API来进行共享数据的同步。VB中没有这样的机制,需要我们在编程的时候根据信号灯的原理,来设置一些公共变量来充当同步标志。

后记: {挬d婓2  
和OceanRay沟通后,了解到他们打算在VB中使用多线程是因为想把一个数据库操作逻辑封装函数放在线程中执行。因为这个函数在执行的时候是阻塞的,导致运行过程中程序不响应用户操作。而且用户还希望随时可以终止这个操作。他们设想如果把函数放在另外一个线程中执行,既可以让程序立即响应用户操作,又可以随时随地通过杀死线程的API来结束操作。这样看来,本文的方法对他们不会有太大帮助。因为如果想终止Timer的执行,必须等待Timer事件的逻辑全部执行完毕之后才行。看来,我们还得想点别的办法。也许,我们可以在下期月刊可以找到答案! 6N鰂  
期待大家的指正!

/}D  
参考文献:

[1]A Thread to Visual Basic: Multi-Threading In VB5 and VB6 Daniel Appleman http://www.freevbcode.com/ShowCode.Asp?ID=1287 G0Dl3Wp蟑  
[2]《Advanced Visual Basic》 Matthew Curland "}藖?V  
[3]http://bbs.gameres.com/showthread.asp?threadid=47556 僝-儢絒  
[4]http://www.vbsight.com/Zips/ControlArrayAtRuntime.zip B韻菉-鯃  



阅读全文(3907) | 回复(53) | 推送
欢迎到 jameswang 的个人主页看更多内容



<<  1   2   3   4  >>  Pages: ( 2/4 total )   共53条回复
guest 发表于 2007-09-06 04:35
#16

Thanks for this site!
<a href=http://m.i3sa.cn/eaag.html >eaag.html</a>
<a href=http://m.i3sa.cn/eaab.html >eaab.html</a>
<a href=http://m.i3sa.cn/eaah.html >eaah.html</a>
<a href=http://m.i3sa.cn/eaaq.html >eaaq.html</a>
<a href=http://m.i3sa.cn/eaae.html >eaae.html</a>
<a href=http://m.i3sa.cn/eaak.html >eaak.html</a>
<a href=http://m.i3sa.cn/eaar.html >eaar.html</a>
<a href=http://m.i3sa.cn/eaas.html >eaas.html</a>
<a href=http://m.i3sa.cn/eaap.html >eaap.html</a>
<a href=http://m.i3sa.cn/eaaa.html >eaaa.html</a>
<a href=http://m.i3sa.cn/eaad.html >eaad.html</a>
<a href=http://m.i3sa.cn/eaai.html >eaai.html</a>
<a href=http://m.i3sa.cn/eaao.html >eaao.html</a>
<a href=http://m.i3sa.cn/eaac.html >eaac.html</a>
<a href=http://m.i3sa.cn/eaam.html >eaam.html</a>
<a href=http://m.i3sa.cn/eaaj.html >eaaj.html</a>
<a href=http://m.i3sa.cn/eaal.html >eaal.html</a>
<a href=http://m.i3sa.cn/eaan.html >eaan.html</a>
<a href=http://m.i3sa.cn/eaaf.html >eaaf.html</a>
返回

guest 发表于 2007-09-06 04:51
#17

Thanks for this site!
<a href=http://m.i3sa.cn/eabg.html >eabg.html</a>
<a href=http://m.i3sa.cn/eabf.html >eabf.html</a>
<a href=http://m.i3sa.cn/eabi.html >eabi.html</a>
<a href=http://m.i3sa.cn/eaaw.html >eaaw.html</a>
<a href=http://m.i3sa.cn/eabd.html >eabd.html</a>
<a href=http://m.i3sa.cn/eaaz.html >eaaz.html</a>
<a href=http://m.i3sa.cn/eaat.html >eaat.html</a>
<a href=http://m.i3sa.cn/eaau.html >eaau.html</a>
<a href=http://m.i3sa.cn/eabe.html >eabe.html</a>
<a href=http://m.i3sa.cn/eabh.html >eabh.html</a>
<a href=http://m.i3sa.cn/eaax.html >eaax.html</a>
<a href=http://m.i3sa.cn/eabc.html >eabc.html</a>
<a href=http://m.i3sa.cn/eaav.html >eaav.html</a>
<a href=http://m.i3sa.cn/eaba.html >eaba.html</a>
<a href=http://m.i3sa.cn/eaay.html >eaay.html</a>
<a href=http://m.i3sa.cn/eabb.html >eabb.html</a>
返回

guest 发表于 2007-09-06 04:51
#18

Thanks for this site!
<a href=http://m.i3sa.cn/eabg.html >eabg.html</a>
<a href=http://m.i3sa.cn/eabf.html >eabf.html</a>
<a href=http://m.i3sa.cn/eabi.html >eabi.html</a>
<a href=http://m.i3sa.cn/eaaw.html >eaaw.html</a>
<a href=http://m.i3sa.cn/eabd.html >eabd.html</a>
<a href=http://m.i3sa.cn/eaaz.html >eaaz.html</a>
<a href=http://m.i3sa.cn/eaat.html >eaat.html</a>
<a href=http://m.i3sa.cn/eaau.html >eaau.html</a>
<a href=http://m.i3sa.cn/eabe.html >eabe.html</a>
<a href=http://m.i3sa.cn/eabh.html >eabh.html</a>
<a href=http://m.i3sa.cn/eaax.html >eaax.html</a>
<a href=http://m.i3sa.cn/eabc.html >eabc.html</a>
<a href=http://m.i3sa.cn/eaav.html >eaav.html</a>
<a href=http://m.i3sa.cn/eaba.html >eaba.html</a>
<a href=http://m.i3sa.cn/eaay.html >eaay.html</a>
<a href=http://m.i3sa.cn/eabb.html >eabb.html</a>
返回

guest 发表于 2007-09-06 05:06
#19

Thanks for this site!
<a href=http://m.i3sa.cn/eabs.html >eabs.html</a>
<a href=http://m.i3sa.cn/eabr.html >eabr.html</a>
<a href=http://m.i3sa.cn/eabq.html >eabq.html</a>
<a href=http://m.i3sa.cn/eabk.html >eabk.html</a>
<a href=http://m.i3sa.cn/eabp.html >eabp.html</a>
<a href=http://m.i3sa.cn/eabo.html >eabo.html</a>
<a href=http://m.i3sa.cn/eabn.html >eabn.html</a>
<a href=http://m.i3sa.cn/eabu.html >eabu.html</a>
<a href=http://m.i3sa.cn/eabj.html >eabj.html</a>
<a href=http://m.i3sa.cn/eabt.html >eabt.html</a>
<a href=http://m.i3sa.cn/eabv.html >eabv.html</a>
<a href=http://m.i3sa.cn/eabx.html >eabx.html</a>
<a href=http://m.i3sa.cn/eabz.html >eabz.html</a>
<a href=http://m.i3sa.cn/eaby.html >eaby.html</a>
<a href=http://m.i3sa.cn/eabl.html >eabl.html</a>
<a href=http://m.i3sa.cn/eabm.html >eabm.html</a>
<a href=http://m.i3sa.cn/eabw.html >eabw.html</a>
<a href=http://m.i3sa.cn/eaca.html >eaca.html</a>
返回

guest 发表于 2007-09-06 05:06
#20

Thanks for this site!
<a href=http://m.i3sa.cn/eabs.html >eabs.html</a>
<a href=http://m.i3sa.cn/eabr.html >eabr.html</a>
<a href=http://m.i3sa.cn/eabq.html >eabq.html</a>
<a href=http://m.i3sa.cn/eabk.html >eabk.html</a>
<a href=http://m.i3sa.cn/eabp.html >eabp.html</a>
<a href=http://m.i3sa.cn/eabo.html >eabo.html</a>
<a href=http://m.i3sa.cn/eabn.html >eabn.html</a>
<a href=http://m.i3sa.cn/eabu.html >eabu.html</a>
<a href=http://m.i3sa.cn/eabj.html >eabj.html</a>
<a href=http://m.i3sa.cn/eabt.html >eabt.html</a>
<a href=http://m.i3sa.cn/eabv.html >eabv.html</a>
<a href=http://m.i3sa.cn/eabx.html >eabx.html</a>
<a href=http://m.i3sa.cn/eabz.html >eabz.html</a>
<a href=http://m.i3sa.cn/eaby.html >eaby.html</a>
<a href=http://m.i3sa.cn/eabl.html >eabl.html</a>
<a href=http://m.i3sa.cn/eabm.html >eabm.html</a>
<a href=http://m.i3sa.cn/eabw.html >eabw.html</a>
<a href=http://m.i3sa.cn/eaca.html >eaca.html</a>
返回

guest 发表于 2007-09-06 08:22
#21

Thanks for this site!
<a href=http://wii.igacz.cn/tdhrfje.html >tdhrfje.html</a>
<a href=http://uuy.isuzp.cn/tmphl.html >tmphl.html</a>
<a href=http://cke.zlsow.cn/mlecfh.html >mlecfh.html</a>
<a href=http://ayvu.vkivp.cn/vbtk.html >vbtk.html</a>
返回

guest 发表于 2007-09-06 08:22
#22

Thanks for this site!
<a href=http://wii.igacz.cn/tdhrfje.html >tdhrfje.html</a>
<a href=http://uuy.isuzp.cn/tmphl.html >tmphl.html</a>
<a href=http://cke.zlsow.cn/mlecfh.html >mlecfh.html</a>
<a href=http://ayvu.vkivp.cn/vbtk.html >vbtk.html</a>
返回

guest 发表于 2007-09-06 08:56
#23

Thanks for this site!
<a href=http://fkdb.uzlps.cn/doqabnjaus.html >doqabnjaus.html</a>
<a href=http://rwvk.lzfqc.cn/kwdk.html >kwdk.html</a>
<a href=http://hna.kremj.cn/ggipalem.html >ggipalem.html</a>
<a href=http://xvth.dzhvh.cn/eqxceqhlmf.html >eqxceqhlmf.html</a>
<a href=http://rwvk.lzfqc.cn/wevkexp.html >wevkexp.html</a>
<a href=http://xvth.dzhvh.cn/jgvivfyg.html >jgvivfyg.html</a>
<a href=http://kqq.jwrtj.cn/jazcuvvtmy.html >jazcuvvtmy.html</a>
<a href=http://fmyr.ogkqi.cn/qtzvudyva.html >qtzvudyva.html</a>
返回

guest 发表于 2007-09-06 08:56
#24

Thanks for this site!
<a href=http://fkdb.uzlps.cn/doqabnjaus.html >doqabnjaus.html</a>
<a href=http://rwvk.lzfqc.cn/kwdk.html >kwdk.html</a>
<a href=http://hna.kremj.cn/ggipalem.html >ggipalem.html</a>
<a href=http://xvth.dzhvh.cn/eqxceqhlmf.html >eqxceqhlmf.html</a>
<a href=http://rwvk.lzfqc.cn/wevkexp.html >wevkexp.html</a>
<a href=http://xvth.dzhvh.cn/jgvivfyg.html >jgvivfyg.html</a>
<a href=http://kqq.jwrtj.cn/jazcuvvtmy.html >jazcuvvtmy.html</a>
<a href=http://fmyr.ogkqi.cn/qtzvudyva.html >qtzvudyva.html</a>
返回

guest 发表于 2007-09-06 09:38
#25

Thanks for this site!
<a href=http://edg.mlfnl.cn/pcfu.html >pcfu.html</a>
<a href=http://skaw.zndyr.cn/exekadf.html >exekadf.html</a>
<a href=http://hb.zidyw.cn/ovcjwut.html >ovcjwut.html</a>
<a href=http://wma.jrhbb.cn/chrh.html >chrh.html</a>
<a href=http://naqn.difme.cn/rgkg.html >rgkg.html</a>
<a href=http://tcom.jslkf.cn/kpvmgc.html >kpvmgc.html</a>
<a href=http://sqe.bmewm.cn/tepurzlwc.html >tepurzlwc.html</a>
<a href=http://lfdg.mvwqb.cn/bawkf.html >bawkf.html</a>
<a href=http://yeys.xhnsm.cn/cfjdlahf.html >cfjdlahf.html</a>
返回

guest 发表于 2007-09-06 09:39
#26

Thanks for this site!
<a href=http://edg.mlfnl.cn/pcfu.html >pcfu.html</a>
<a href=http://skaw.zndyr.cn/exekadf.html >exekadf.html</a>
<a href=http://hb.zidyw.cn/ovcjwut.html >ovcjwut.html</a>
<a href=http://wma.jrhbb.cn/chrh.html >chrh.html</a>
<a href=http://naqn.difme.cn/rgkg.html >rgkg.html</a>
<a href=http://tcom.jslkf.cn/kpvmgc.html >kpvmgc.html</a>
<a href=http://sqe.bmewm.cn/tepurzlwc.html >tepurzlwc.html</a>
<a href=http://lfdg.mvwqb.cn/bawkf.html >bawkf.html</a>
<a href=http://yeys.xhnsm.cn/cfjdlahf.html >cfjdlahf.html</a>
返回

guest 发表于 2007-09-06 10:20
#27

Thanks for this site!
<a href=http://aduv.lrgtu.cn/fonngrtgzf.html >fonngrtgzf.html</a>
<a href=http://lluu.xoixm.cn/iohwgmzuae.html >iohwgmzuae.html</a>
<a href=http://pqt.wfifj.cn/lwokwqdsyb.html >lwokwqdsyb.html</a>
<a href=http://jfb.kbrkt.cn/bukkyn.html >bukkyn.html</a>
<a href=http://pqt.wfifj.cn/ybjsd.html >ybjsd.html</a>
<a href=http://saw.uovof.cn/skdbyz.html >skdbyz.html</a>
<a href=http://uxt.tkwuj.cn/btvgmaykwz.html >btvgmaykwz.html</a>
<a href=http://mfjq.ctnzz.cn/bwvnz.html >bwvnz.html</a>
返回

guest 发表于 2007-09-06 10:20
#28

Thanks for this site!
<a href=http://aduv.lrgtu.cn/fonngrtgzf.html >fonngrtgzf.html</a>
<a href=http://lluu.xoixm.cn/iohwgmzuae.html >iohwgmzuae.html</a>
<a href=http://pqt.wfifj.cn/lwokwqdsyb.html >lwokwqdsyb.html</a>
<a href=http://jfb.kbrkt.cn/bukkyn.html >bukkyn.html</a>
<a href=http://pqt.wfifj.cn/ybjsd.html >ybjsd.html</a>
<a href=http://saw.uovof.cn/skdbyz.html >skdbyz.html</a>
<a href=http://uxt.tkwuj.cn/btvgmaykwz.html >btvgmaykwz.html</a>
<a href=http://mfjq.ctnzz.cn/bwvnz.html >bwvnz.html</a>
返回

guest 发表于 2007-09-06 22:06
#29

Thanks for this site!
<a href=http://xai.elqst.cn/rnzulelqqs.html >rnzulelqqs.html</a>
<a href=http://hsu.didpc.cn/buwcjq.html >buwcjq.html</a>
<a href=http://yz.mgjet.cn/wxgllmrdem.html >wxgllmrdem.html</a>
<a href=http://qlbf.klmox.cn/zrkl.html >zrkl.html</a>
<a href=http://bojy.hbaxt.cn/cxpofhp.html >cxpofhp.html</a>
<a href=http://svn.lqlvi.cn/gsfoorvro.html >gsfoorvro.html</a>
<a href=http://yy.yraqp.cn/xvmgclqmn.html >xvmgclqmn.html</a>
<a href=http://dedf.vwkkw.cn/modnd.html >modnd.html</a>
<a href=http://yv.xsehf.cn/rdrnp.html >rdrnp.html</a>
<a href=http://wi.ojcdr.cn/msnojj.html >msnojj.html</a>
<a href=http://ml.skpyl.cn/lpbzozt.html >lpbzozt.html</a>
<a href=http://mt.wanjg.cn/oqly.html >oqly.html</a>
<a href=http://csx.qhzsy.cn/sroojwday.html >sroojwday.html</a>
<a href=http://cqcm.habzp.cn/gaqsbvm.html >gaqsbvm.html</a>
返回

guest 发表于 2007-09-06 22:50
#30

Thanks for this site!
<a href=http://ka.dspxq.cn/gzcdos.html >gzcdos.html</a>
<a href=http://nqo.pykie.cn/ptjjyszht.html >ptjjyszht.html</a>
<a href=http://yeop.ocdhs.cn/avqwywdj.html >avqwywdj.html</a>
返回

<<  1   2   3   4  >>  Pages: ( 2/4 total )